[ --enable-macosx MacOS X support (default enabled on MacOS X)],
[if test "${enable_macosx}" = "yes"
then
- VLC_ADD_BUILTINS([macosx])
- VLC_ADD_LDFLAGS([macosx],[-framework IOKit -framework Cocoa -framework Carbon -framework QuickTime -lobjc -ObjC -framework OpenGL -framework AGL])
+ VLC_ADD_PLUGINS([access_eyetv])
+ VLC_ADD_LDFLAGS([access_eyetv], [-framework CoreFoundation])
+ VLC_ADD_LDFLAGS([macosx],[-framework IOKit -framework Cocoa -framework Carbon -framework QuickTime -lobjc -ObjC -framework OpenGL -framework AGL -framework QTKit])
VLC_ADD_OBJCFLAGS( [macosx],[-fobjc-exceptions] )
fi],
[AC_CHECK_HEADERS(Cocoa/Cocoa.h,
+ VLC_ADD_PLUGINS([access_eyetv])
+ VLC_ADD_LDFLAGS([access_eyetv], [-framework CoreFoundation])
VLC_ADD_BUILTINS([macosx])
- VLC_ADD_LDFLAGS([macosx],[-framework IOKit -framework Cocoa -framework Carbon -framework QuickTime -lobjc -ObjC -framework OpenGL -framework AGL])
+ VLC_ADD_LDFLAGS([macosx],[-framework IOKit -framework Cocoa -framework Carbon -framework QuickTime -lobjc -ObjC -framework OpenGL -framework AGL -framework QTKit])
VLC_ADD_OBJCFLAGS( [macosx],[-fobjc-exceptions] )
)])
CFLAGS=$ORIGCFLAGS
--- /dev/null
+/* This is public domain code developed by Elgato Systems GmbH. No GPL-covered \r
+ * changes were added to this file by any members of the VideoLAN team. If you\r
+ * want to do so, add a modified GPL header here, but keep a message emphasising\r
+ * the non-licensed parts of this header file. \r
+ * Ideally, VideoLAN-related changes should only go to eyetvplugin.h.\r
+ * \r
+ * $Id$\r
+ */\r
+\r
+\r
+#pragma once\r
+\r
+/*\r
+\r
+ The EyeTV Plugin API\r
+ ====================\r
+ \r
+ The EyeTV Software gives third parties access to the incoming MPEG-2 transport stream. \r
+ At this time the API is available for the following products:\r
+ \r
+ - EyeTV 200 (analog)\r
+ - EyeTV 300 (DVB-S) \r
+ - EyeTV 400 (DVB-T)\r
+ \r
+ A plugin receives device plugged/unplugged notifications, it can request or release \r
+ individual PIDs and most importantly it has access to transport stream packets in \r
+ real time, as they arrive from the device. Note that the plugin is called before EyeTV \r
+ itself looks at the packets, so it is even possible to modify the data.\r
+ \r
+ Plugins currently live in EyeTV.app/Contens/Plugins/\r
+ \r
+ A plugin is packaged as a bundle with a single entry point:\r
+ \r
+ long EyeTVPluginDispatcher(EyeTVPluginSelector selector, \r
+ void *refCon, \r
+ EyeTVPluginDeviceID deviceID, \r
+ long param1, \r
+ long param2, \r
+ long param3, \r
+ long param4);\r
+\r
+ \r
+ PID Filtering\r
+ =============\r
+ \r
+ EyeTV employs both hardware and software PID filtering. A plugin's dispatch routine \r
+ is called with the kEyeTVPluginSelector_PacketsArrived selector after the hardware \r
+ PID filter (naturally) but prior to the software PID filter, so the plugin has access \r
+ to all packets that are delivered by the hardware. \r
+ \r
+ A plugin can request PIDs that are not needed by EyeTV from the hardware PID filter by \r
+ means of a callback routine, see eyeTVPluginSelector_SetCallback.\r
+\r
+ Note that hardware PID filtering is on for single processor machines (to reduce the CPU \r
+ load), but off for multi-processor machines (to improve channel switch times). \r
+ This behaviour is controlled by the "hardware PID filter" key in com.elgato.eyetv.plist, \r
+ which defaults to "Auto" ("Off" on MP machines, "On" on single-processor machines). EyeTV\r
+ does not offer GUI to change this setting. A plugin hence needs to be prepared to handle \r
+ both an entire transponder or multiplex and to request PIDs it might need.\r
+ \r
+ Note that the plugin is called on the real-time thread that receives the transport stream\r
+ packets and that the packet buffers passed to the plugin are the actual hardware DMA buffers.\r
+ Please return as quickly as possible from the kEyeTVPluginSelector_PacketsArrived call and\r
+ avoid blocking the calling thread.\r
+\r
+\r
+\r
+\r
+\r
+ Revision History:\r
+\r
+ 02/27/2004: Initial Release.\r
+\r
+*/\r
+ \r
+\r
+\r
+#define EYETV_PLUGIN_API_VERSION 0x04021901\r
+#define EYETV_PLUGIN_API_MIN_VERSION 0x04021901\r
+\r
+typedef long long EyeTVPluginDeviceID;\r
+typedef long EyeTVPluginDeviceType;\r
+typedef long EyeTVPluginSelector;\r
+\r
+enum {\r
+ kEyeTVPIDType_Video = 0,\r
+ kEyeTVPIDType_MPEGAudio = 1,\r
+ kEyeTVPIDType_VBI = 2, /* teletext */\r
+ kEyeTVPIDType_PCR = 3,\r
+ kEyeTVPIDType_PMT = 4,\r
+ kEyeTVPIDType_Unknown = 5,\r
+ kEyeTVPIDType_AC3Audio = 6\r
+};\r
+\r
+\r
+typedef struct EyeTVPluginPIDInfo EyeTVPluginPIDInfo;\r
+struct EyeTVPluginPIDInfo {\r
+ long pid;\r
+ long pidType; \r
+};\r
+\r
+\r
+\r
+/***********************************************************************************\r
+*\r
+* EyeTVPluginCallbackParams,\r
+*\r
+***********************************************************************************/\r
+enum {\r
+ kEyeTVPluginCallbackSelector_RetainPIDs = 0, \r
+ kEyeTVPluginCallbackSelector_ReleasePIDs = 1 \r
+};\r
+\r
+typedef struct EyeTVPluginCallbackParams EyeTVPluginCallbackParams; \r
+struct EyeTVPluginCallbackParams {\r
+ EyeTVPluginDeviceID deviceID; // the deviceID\r
+ long selector; // callback selector, see above\r
+ long *pids; // list of pids to release/retain\r
+ long pidsCount; // count of pids\r
+};\r
+\r
+\r
+/***********************************************************************************\r
+*\r
+* typedef for the callback function,\r
+*\r
+***********************************************************************************/\r
+typedef long(* EyeTVPluginCallbackProc)(EyeTVPluginCallbackParams *params);\r
+\r
+\r
+\r
+/***********************************************************************************\r
+*\r
+* EyeTVPluginParamStructs\r
+*\r
+***********************************************************************************/\r
+\r
+\r
+typedef struct EyeTVPluginInitializeParams EyeTVPluginInitializeParams;\r
+struct EyeTVPluginInitializeParams {\r
+ long apiVersion; // version of the EyeTV_PLUGIN_API\r
+ EyeTVPluginCallbackProc callback; // the callback\r
+}; /* 8 bytes */\r
+\r
+\r
+\r
+typedef struct EyeTVPluginGetInfoParams EyeTVPluginGetInfoParams;\r
+struct EyeTVPluginGetInfoParams {\r
+ long *pluginAPIVersion; // <- EYETV_PLUGIN_API_VERSION\r
+ char *pluginName; // <- points to a 128-byte buffer, the plugin is expected to fill the buffer with\r
+ // a UTF-8 encoded string. \r
+ char *description; // <- points to a 1024-byte buffer, the plugin is expected to fill the buffer with\r
+ // a UTF-8 encoded string describing the plugin.\r
+}; /* 12 bytes */\r
+\r
+\r
+\r
+enum {\r
+ kEyeTVPluginDeviceType_Unknown = 0, \r
+ kEyeTVPluginDeviceType_e200 = 1,\r
+ kEyeTVPluginDeviceType_e300 = 2,\r
+ kEyeTVPluginDeviceType_e400 = 3\r
+} ;\r
+\r
+typedef struct EyeTVPluginDeviceAddedParams EyeTVPluginDeviceAddedParams;\r
+struct EyeTVPluginDeviceAddedParams {\r
+ EyeTVPluginDeviceType deviceType; \r
+}; /* 4 bytes */\r
+\r
+\r
+typedef struct EyeTVPluginPacketsArrivedParams EyeTVPluginPacketsArrivedParams;\r
+struct EyeTVPluginPacketsArrivedParams {\r
+ long **packets; // points to an array of packets\r
+ long packetCount; \r
+}; /* 8 bytes */\r
+\r
+\r
+\r
+typedef struct EyeTVPluginServiceChangedParams EyeTVPluginServiceChangedParams;\r
+struct EyeTVPluginServiceChangedParams {\r
+ long headendID; // new headend ID. For E300 it's the orbital position of the satellite\r
+ // in tenth of a degree\r
+ long transponderID; // new transponder ID (The Frequency in kHz)\r
+ long serviceID; // new service ID (the ID of the used service as included in the DVB Stream)\r
+ EyeTVPluginPIDInfo *pidList; // points to the list of active PIDs;\r
+ long pidCount; // the length of pidList\r
+}; /* 20 bytes */\r
+\r
+\r
+\r
+\r
+/***********************************************************************************\r
+*\r
+* EyeTVPluginParams\r
+* \r
+***********************************************************************************/\r
+typedef struct EyeTVPluginParams EyeTVPluginParams;\r
+struct EyeTVPluginParams {\r
+ EyeTVPluginDeviceID deviceID; // ID of the device\r
+ EyeTVPluginSelector selector; // selector\r
+ void *refCon; // refCon\r
+\r
+ union { \r
+ EyeTVPluginInitializeParams initialize; // kEyeTVPluginSelector_Initialize\r
+ // kEyeTVPluginSelector_Terminate, no additional parameters\r
+ EyeTVPluginGetInfoParams info; // kEyeTVPluginSelector_GetInfo\r
+ EyeTVPluginDeviceAddedParams deviceAdded; // kEyeTVPluginSelector_DeviceAdded\r
+ // kEyeTVPluginSelector_DeviceRemoved, no additional parameters\r
+ EyeTVPluginPacketsArrivedParams packetsArrived; // kEyeTVPluginSelector_PacketsArrived\r
+ EyeTVPluginServiceChangedParams serviceChanged; // kEyeTVPluginSelector_ServiceChanged\r
+ \r
+ };\r
+};\r
+\r
+\r
+enum { // EyeTVPluginSelector\r
+ kEyeTVPluginSelector_Initialize = 0, \r
+ kEyeTVPluginSelector_Terminate = 1, \r
+ kEyeTVPluginSelector_GetInfo = 2, \r
+ kEyeTVPluginSelector_DeviceAdded = 3, \r
+ kEyeTVPluginSelector_DeviceRemoved = 4, \r
+ kEyeTVPluginSelector_PacketsArrived = 5, \r
+ kEyeTVPluginSelector_ServiceChanged = 6 \r
+}; \r
+\r
+\r
+\r
+/***********************************************************************************\r
+*\r
+* EyeTVPluginEntryProc\r
+*\r
+***********************************************************************************/\r
+typedef long(* EyeTVPluginEntryProc)(EyeTVPluginParams *params);\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>org.videolan.vlceyetvplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>CFPlugInFactories</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <string>MyFactoryFunction</string>
+ </dict>
+ <key>CFPlugInTypes</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <array>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </array>
+ </dict>
+ <key>CFPlugInUnloadFunction</key>
+ <string></string>
+</dict>
+</plist>
--- /dev/null
+/*****************************************************************************\r
+* eyetvplugin.c: Plug-In for the EyeTV software to connect to VLC\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
+#include "eyetvplugin.h"\r
+\r
+#define MAX_PIDS 256\r
+#define MAX_ACTIVE_PIDS 256\r
+#define MAX_DEVICES 16\r
+#define VLC_NOTIFICATION_OBJECT "VLCEyeTVSupport"\r
+\r
+#pragma push\r
+#pragma pack(1)\r
+\r
+\r
+/* Structure for TS-Packets */\r
+typedef struct \r
+{\r
+ unsigned long sync_byte : 8,\r
+ transport_error_indicator : 1,\r
+ payload_unit_start_indicator : 1,\r
+ transport_priority : 1,\r
+ PID : 13,\r
+ transport_scrambling_control : 2,\r
+ adaptation_field_control : 2,\r
+ continuity_counter : 4;\r
+\r
+ unsigned char data[188-4];\r
+\r
+} TransportStreamPacket;\r
+\r
+#pragma pop\r
+\r
+\r
+/* Structure to hold Information on devices */\r
+typedef struct\r
+{\r
+ EyeTVPluginDeviceID deviceID;\r
+ EyeTVPluginDeviceType deviceType;\r
+\r
+ long headendID;\r
+ long transponderID;\r
+ long serviceID;\r
+\r
+ long pidsCount;\r
+ long pids[MAX_PIDS];\r
+\r
+ EyeTVPluginPIDInfo activePIDs[MAX_ACTIVE_PIDS];\r
+ long activePIDsCount;\r
+\r
+} DeviceInfo;\r
+\r
+\r
+/* Structure to hold global data to communicate with EyeTV */\r
+typedef struct \r
+{\r
+ EyeTVPluginCallbackProc callback;\r
+ long deviceCount;\r
+ DeviceInfo devices[MAX_DEVICES];\r
+ long long packetCount;\r
+\r
+} VLCEyeTVPluginGlobals_t;\r
+\r
+/* 2nd structure to store our own global data which isn't shared with EyeTV\r
+ * a bit empty at the moment, but it will get larger as development progresses */\r
+typedef struct\r
+{\r
+ int i_deviceCount;\r
+ CFMessagePortRef messagePortToVLC;\r
+ bool b_msgPortOpen;\r
+} VLCEyeTVPluginOwnGlobals_t;\r
+\r
+VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+\r
+\r
+/* return the DeviceInfo with ID deviceID */\r
+static DeviceInfo *GetDeviceInfo(VLCEyeTVPluginGlobals_t *globals, EyeTVPluginDeviceID deviceID)\r
+{\r
+ int i;\r
+ \r
+ if( globals ) \r
+ {\r
+ for( i=0; i<globals->deviceCount; i++) \r
+ {\r
+ if( globals->devices[i].deviceID == deviceID ) \r
+ {\r
+ return &globals->devices[i];\r
+ }\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+#pragma mark -\r
+\r
+/* initialise the plug-in */\r
+static long VLCEyeTVPluginInitialize(VLCEyeTVPluginGlobals_t** globals, long apiVersion, EyeTVPluginCallbackProc callback)\r
+{\r
+ printf("VLC media player Plug-In: Initialize\n");\r
+ long result = 0;\r
+ \r
+ /* init our own storage */\r
+ extern VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+ nativeGlobals = malloc( sizeof( VLCEyeTVPluginOwnGlobals_t ) );\r
+ \r
+ /* notify a potential VLC instance about our initialisation */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter(),\r
+ CFSTR("PluginInit"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ \r
+ /* init our notification support */\r
+ CFNotificationCenterAddObserver( CFNotificationCenterGetDistributedCenter(),\r
+ /* observer */ NULL, \r
+ /* callBack */ VLCEyeTVPluginGlobalNotificationReceived,\r
+ /* name, NULL==all */ NULL,\r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ CFNotificationSuspensionBehaviorDeliverImmediately );\r
+ \r
+ *globals = (VLCEyeTVPluginGlobals_t *) calloc(1, sizeof( VLCEyeTVPluginGlobals_t ) );\r
+ ( *globals )->callback = callback;\r
+ \r
+ return result;\r
+}\r
+\r
+/* we will be terminated soon, clean up */\r
+static long VLCEyeTVPluginTerminate(VLCEyeTVPluginGlobals_t *globals)\r
+{\r
+ extern VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+ \r
+ printf("VLC media player Plug-In: Terminate\n");\r
+ \r
+ long result = 0;\r
+ \r
+ /* notify a potential VLC instance about our termination */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter (),\r
+ CFSTR("PluginQuit"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ \r
+ /* remove us from the global notification centre */\r
+ CFNotificationCenterRemoveEveryObserver( CFNotificationCenterGetDistributedCenter(),\r
+ (void *)VLCEyeTVPluginGlobalNotificationReceived );\r
+ \r
+ /* invalidate and free msg port */\r
+ if( nativeGlobals->messagePortToVLC )\r
+ {\r
+ CFMessagePortInvalidate( nativeGlobals->messagePortToVLC );\r
+ free( nativeGlobals->messagePortToVLC );\r
+ printf( "msgport invalidated and freed\n" );\r
+ }\r
+ else\r
+ printf( "no msgport to free\n" );\r
+ \r
+ if( globals ) \r
+ {\r
+ free( globals );\r
+ }\r
+\r
+ if( nativeGlobals )\r
+ free( nativeGlobals );\r
+ \r
+ return result;\r
+}\r
+\r
+/* called when EyeTV asks various stuff about us */\r
+static long VLCEyeTVPluginGetInformation(VLCEyeTVPluginGlobals_t *globals, long* outAPIVersion, char* outName, char *outDescription)\r
+{\r
+ printf("VLC media player Plug-In: GetInfo\n");\r
+ long result = 0;\r
+ \r
+ if( globals ) \r
+ {\r
+ if( outAPIVersion )\r
+ {\r
+ *outAPIVersion = EYETV_PLUGIN_API_VERSION;\r
+ }\r
+ \r
+ if( outName )\r
+ {\r
+ char* name = "VLC media player Plug-In";\r
+ strcpy( &outName[0], name);\r
+ }\r
+ \r
+ if( outDescription )\r
+ {\r
+ char* desc = "This Plug-In connects EyeTV to the VLC media player for streaming purposes.";\r
+ strcpy( &outDescription[0], desc);\r
+ }\r
+ }\r
+ \r
+ return result;\r
+}\r
+\r
+/* called if we received a global notification */\r
+void VLCEyeTVPluginGlobalNotificationReceived( CFNotificationCenterRef center, \r
+ void *observer, \r
+ CFStringRef name, \r
+ const void *object, \r
+ CFDictionaryRef userInfo )\r
+{\r
+ CFIndex maxlen;\r
+ char *theName, *theObject;\r
+ extern VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+\r
+ maxlen = CFStringGetMaximumSizeForEncoding( CFStringGetLength( name ),\r
+ kCFStringEncodingUTF8) + 1;\r
+ theName = malloc(maxlen);\r
+ CFStringGetCString( name, \r
+ theName, \r
+ maxlen,\r
+ kCFStringEncodingUTF8);\r
+ \r
+ maxlen = CFStringGetMaximumSizeForEncoding( CFStringGetLength( name ),\r
+ kCFStringEncodingUTF8) + 1;\r
+ theObject = malloc(maxlen);\r
+ CFStringGetCString( object, \r
+ theObject, \r
+ maxlen,\r
+ kCFStringEncodingUTF8);\r
+ printf( "notication received with name: %s and object: %s\n", theName, theObject );\r
+ \r
+ /* when VLC launches after us, we need to inform it about our existance and the current state of available devices */\r
+ if( CFStringCompare( name, CFSTR( "VLCOSXGUIInit" ), 0) == kCFCompareEqualTo )\r
+ {\r
+ /* we're here */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter (),\r
+ CFSTR("PluginInit"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ if( nativeGlobals && ( nativeGlobals->i_deviceCount > 0 ) )\r
+ {\r
+ /* at least one device is apparently connected */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter (),\r
+ CFSTR("DeviceAdded"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ }\r
+ }\r
+ \r
+ /* VLC wants us to start sending data */\r
+ if( CFStringCompare( name, CFSTR( "VLCAccessStartDataSending" ), 0) == kCFCompareEqualTo )\r
+ {\r
+ nativeGlobals->messagePortToVLC = CFMessagePortCreateRemote( kCFAllocatorDefault,\r
+ CFSTR("VLCEyeTVMsgPort") );\r
+ if( nativeGlobals->messagePortToVLC == NULL )\r
+ printf( "getting messagePortToVLC failed!\n" );\r
+ else\r
+ {\r
+ nativeGlobals->b_msgPortOpen = TRUE;\r
+ printf( "msg port opened / data sending switched on\n" );\r
+ }\r
+ }\r
+ \r
+ /* VLC wants us to stop sending data */\r
+ if( CFStringCompare( name, CFSTR( "VLCAccessStopDataSending" ), 0) == kCFCompareEqualTo )\r
+ {\r
+ nativeGlobals->b_msgPortOpen = FALSE;\r
+ printf( "data sending switched off\n" );\r
+ }\r
+}\r
+\r
+/* called if a device is added */\r
+static long VLCEyeTVPluginDeviceAdded(VLCEyeTVPluginGlobals_t *globals, EyeTVPluginDeviceID deviceID, EyeTVPluginDeviceType deviceType)\r
+{\r
+ printf("VLC media player Plug-In: Device with type %i and ID %i added\n", (int)deviceType, (int)deviceID);\r
+ \r
+ long result = 0;\r
+ DeviceInfo *deviceInfo;\r
+ extern VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+ \r
+ \r
+ if( globals ) \r
+ {\r
+ if( globals->deviceCount < MAX_DEVICES ) \r
+ {\r
+ deviceInfo = &( globals->devices[globals->deviceCount] );\r
+ memset(deviceInfo, 0, sizeof(DeviceInfo));\r
+ \r
+ deviceInfo->deviceID = deviceID;\r
+ deviceInfo->deviceType = deviceType;\r
+\r
+ globals->deviceCount++;\r
+\r
+ if( nativeGlobals )\r
+ nativeGlobals->i_deviceCount = globals->deviceCount;\r
+\r
+ /* notify a potential VLC instance about the addition */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter(),\r
+ CFSTR("DeviceAdded"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ }\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+/* called if a device is removed */\r
+static long VLCEyeTVPluginDeviceRemoved(VLCEyeTVPluginGlobals_t *globals, EyeTVPluginDeviceID deviceID)\r
+{\r
+ printf("VLC media player Plug-In: DeviceRemoved\n");\r
+ \r
+ extern VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+ long result = 0;\r
+ int i;\r
+ \r
+ if( globals ) \r
+ {\r
+ for( i = 0; i < globals->deviceCount; i++ )\r
+ {\r
+ if ( globals->devices[i].deviceID == deviceID ) \r
+ {\r
+ globals->deviceCount--;\r
+\r
+ if( i<globals->deviceCount )\r
+ {\r
+ globals->devices[i] = globals->devices[globals->deviceCount];\r
+ }\r
+ \r
+ if( nativeGlobals )\r
+ nativeGlobals->i_deviceCount = globals->deviceCount;\r
+ \r
+ /* notify a potential VLC instance about the removal */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter(),\r
+ CFSTR("DeviceRemoved"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ }\r
+ }\r
+ }\r
+ \r
+ return result;\r
+}\r
+\r
+/* This function is called, whenever packets are received by EyeTV. For reasons of performance,\r
+ * the data is the original data, not a copy. That means, EyeTV waits until this method is \r
+ * finished. Therefore all in this method should be as fast as possible. */\r
+int i=0;\r
+static long VLCEyeTVPluginPacketsArrived(VLCEyeTVPluginGlobals_t *globals, EyeTVPluginDeviceID deviceID, long **packets, long packetsCount)\r
+{\r
+ long result = 0;\r
+ int i, j, isNewPID;\r
+ TransportStreamPacket *packet;\r
+ extern VLCEyeTVPluginOwnGlobals_t *nativeGlobals;\r
+ SInt32 i_returnValue;\r
+ CFMutableDataRef theMutableRef;\r
+ uint8_t *p_bufferForSending = malloc(4);\r
+ bool b_nonSendData;\r
+ int i_lastSentPacket;\r
+ \r
+ if( globals && nativeGlobals ) \r
+ {\r
+ DeviceInfo *deviceInfo = GetDeviceInfo(globals, deviceID);\r
+\r
+ if( deviceInfo ) \r
+ {\r
+ /* alloc the buffer if wanted */\r
+ if( nativeGlobals->b_msgPortOpen == TRUE )\r
+ theMutableRef = CFDataCreateMutable( kCFAllocatorDefault, (188) );\r
+ \r
+ for( i = 0; i < packetsCount; i++ ) \r
+ {\r
+ packet = ( TransportStreamPacket* )packets[i];\r
+ isNewPID = 1;\r
+ \r
+ /* search for PID */\r
+ for( j = 0; j < deviceInfo->pidsCount; j++ ) \r
+ {\r
+ if( packet->PID == deviceInfo->pids[j] ) \r
+ {\r
+ isNewPID = 0;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /* add new PIDs to the DeviceInfo */\r
+ if( isNewPID ) \r
+ {\r
+ printf ("VLC media player Plug-In: SamplePacketsArrived, newPID = %6d\n", packet->PID);\r
+ \r
+ if( deviceInfo->pidsCount < MAX_PIDS ) \r
+ {\r
+ deviceInfo->pids[deviceInfo->pidsCount++] = packet->PID;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* forward data to VLC if wanted */\r
+ /* FIXME: we only receive ARD for now */\r
+ if( nativeGlobals->b_msgPortOpen == TRUE && (\r
+ packet->PID == 1401 ||\r
+ packet->PID == 1402 ||\r
+ packet->PID == 1400 ||\r
+ packet->PID == 1404 ||\r
+ packet->PID == 3070 ||\r
+ packet->PID == 3072 ||\r
+ packet->PID == 3074 ||\r
+ packet->PID == 5074 ||\r
+ packet->PID == 0 ||\r
+ packet->PID == 17 ||\r
+ packet->PID == 19 ||\r
+ packet->PID == 20 ) )\r
+ {\r
+ /* in a good world, this wouldn't be necessary */\r
+ if( theMutableRef == NULL )\r
+ theMutableRef = CFDataCreateMutable( kCFAllocatorDefault, (188) );\r
+ \r
+ /* collect data to send larger packets */\r
+ \r
+ /* enlarge buffer if necessary */\r
+ if( i > 0 )\r
+ CFDataIncreaseLength( theMutableRef, 188 );\r
+ \r
+ /* add missing header */\r
+ memcpy( p_bufferForSending, packet, 4 );\r
+ CFDataAppendBytes( theMutableRef, p_bufferForSending, sizeof(p_bufferForSending) );\r
+\r
+ free( p_bufferForSending );\r
+ p_bufferForSending = malloc(4);\r
+ \r
+ /* add payload */\r
+ CFDataAppendBytes( theMutableRef, packet->data, sizeof(packet->data) );\r
+ \r
+ b_nonSendData = TRUE;\r
+ \r
+ }\r
+ }\r
+ \r
+ globals->packetCount++;\r
+ \r
+ if( globals->packetCount%10000 == 0 ) \r
+ printf("-> %lld Packets received so far...\n",globals->packetCount);\r
+ }\r
+\r
+ if( nativeGlobals->b_msgPortOpen == TRUE )\r
+ {\r
+ printf( "sending %i bytes of data\n", CFDataGetLength( theMutableRef ) );\r
+ i_returnValue = CFMessagePortSendRequest( nativeGlobals->messagePortToVLC,\r
+ /* arbitrary int val */ globals->packetCount,\r
+ /* the data */ theMutableRef,\r
+ /* no timeout for sending */ 0,\r
+ /* no timeout for resp */ 0,\r
+ /* no resp. wanted */ NULL,\r
+ NULL );\r
+ b_nonSendData = FALSE;\r
+ i_lastSentPacket = globals->packetCount;\r
+ if( i_returnValue == kCFMessagePortSendTimeout )\r
+ printf( "time out while sending\n" );\r
+ else if( i_returnValue == kCFMessagePortReceiveTimeout )\r
+ printf( "time out while waiting for resp\n" );\r
+ else if( i_returnValue == kCFMessagePortIsInvalid )\r
+ {\r
+ /* suppress any further attemps */ \r
+ printf( "message port is invalid!\n" );\r
+ nativeGlobals->b_msgPortOpen = FALSE;\r
+ }\r
+ else if( i_returnValue == kCFMessagePortTransportError ) \r
+ printf( "transport error while sending!\n" );\r
+ else\r
+ {\r
+ //printf( "success, freeing resources\n" );\r
+ free( theMutableRef );\r
+ theMutableRef = CFDataCreateMutable( kCFAllocatorDefault, (188) );\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+ else\r
+ printf( "warning: either globals or nativeGlobals are NIL in VLCEyeTVPluginPacketsArrived" );\r
+\r
+ /* clean up before leaving function */\r
+ //if( nativeGlobals->b_msgPortOpen == TRUE )\r
+ // free( theMutableRef );\r
+ \r
+ free( p_bufferForSending );\r
+ \r
+ return result;\r
+}\r
+\r
+/* VLCEyeTVPluginServiceChanged,\r
+ *\r
+ * - *globals : The plug-in Globals\r
+ * - deviceID : Identifies the active Device\r
+ * - headendID : The HeadendID, for e300 it's the orbital position of the satelite in \r
+ * tenth degrees east\r
+ * - transponderID : The Frequency in kHz\r
+ * - serviceID : original ServiceID from the DVB-Stream (e300, e400)\r
+ * - pidList : List of active PIDs \r
+ *\r
+ * Whenever a service changes, this function is called. Service-related plug-in data should be updated here.\r
+ */\r
+static long VLCEyeTVPluginServiceChanged(VLCEyeTVPluginGlobals_t *globals, \r
+ EyeTVPluginDeviceID deviceID, \r
+ long headendID, \r
+ long transponderID, \r
+ long serviceID, \r
+ EyeTVPluginPIDInfo *pidList, \r
+ long pidsCount)\r
+{\r
+ long result = 0;\r
+ int i;\r
+ \r
+ printf("\nVLC media player Plug-In: ServiceChanged:\n");\r
+ printf( "=====================================\n");\r
+ \r
+ if( globals ) \r
+ {\r
+ DeviceInfo *deviceInfo = GetDeviceInfo( globals, deviceID );\r
+ if( deviceInfo ) \r
+ {\r
+ deviceInfo->headendID = headendID;\r
+ printf("HeadendID: %ld, ", headendID);\r
+ \r
+ deviceInfo->transponderID = transponderID;\r
+ printf("TransponderID: %ld, ", transponderID);\r
+ \r
+ deviceInfo->serviceID = serviceID;\r
+ printf("ServiceID: %ld\n\n", serviceID);\r
+ \r
+ deviceInfo->activePIDsCount = pidsCount;\r
+\r
+ for( i = 0; i < pidsCount; i++ )\r
+ {\r
+ deviceInfo->activePIDs[i] = pidList[i];\r
+ printf("Active PID: %ld, type: %ld\n", pidList[i].pid, pidList[i].pidType);\r
+ }\r
+\r
+ deviceInfo->pidsCount = 0;\r
+ \r
+ }\r
+ }\r
+ printf( "=====================================\n");\r
+ \r
+ /* notify a potential VLC instance about the service change */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter(),\r
+ CFSTR("ServiceChanged"), \r
+ CFSTR(VLC_NOTIFICATION_OBJECT), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ \r
+ return result;\r
+}\r
+\r
+\r
+#pragma mark -\r
+/* EyeTVPluginDispatcher,\r
+ *\r
+ * - selector : See 'EyeTVPluginDefs.h'\r
+ * - *refCon : The RefCon to the plug-in-related Data\r
+ * - deviceID : Identifies the Device\r
+ * - params : Parameters for functioncall\r
+ *\r
+ * This function is a part of the interface for the communication with EyeTV. If something happens,\r
+ * EyeTV thinks, we should know of, it calls this function with the corresponding selector. */\r
+\r
+#pragma export on\r
+\r
+long EyeTVPluginDispatcher( EyeTVPluginParams* params )\r
+{\r
+ long result = 0;\r
+\r
+ switch( params->selector ) \r
+ {\r
+ case kEyeTVPluginSelector_Initialize:\r
+ result = VLCEyeTVPluginInitialize((VLCEyeTVPluginGlobals_t**)params->refCon, \r
+ params->initialize.apiVersion, params->initialize.callback);\r
+ break;\r
+ \r
+ case kEyeTVPluginSelector_Terminate:\r
+ result = VLCEyeTVPluginTerminate((VLCEyeTVPluginGlobals_t*)params->refCon);\r
+ break;\r
+\r
+ case kEyeTVPluginSelector_GetInfo:\r
+ result = VLCEyeTVPluginGetInformation((VLCEyeTVPluginGlobals_t*)params->refCon, \r
+ params->info.pluginAPIVersion, params->info.pluginName, params->info.description);\r
+ break;\r
+\r
+ case kEyeTVPluginSelector_DeviceAdded:\r
+ result = VLCEyeTVPluginDeviceAdded((VLCEyeTVPluginGlobals_t*)params->refCon, \r
+ params->deviceID, params->deviceAdded.deviceType);\r
+ break;\r
+ \r
+ case kEyeTVPluginSelector_DeviceRemoved:\r
+ result = VLCEyeTVPluginDeviceRemoved((VLCEyeTVPluginGlobals_t*)params->refCon, params->deviceID);\r
+ break;\r
+\r
+ case kEyeTVPluginSelector_PacketsArrived:\r
+ result = VLCEyeTVPluginPacketsArrived((VLCEyeTVPluginGlobals_t*)params->refCon, params->deviceID, \r
+ params->packetsArrived.packets, params->packetsArrived.packetCount);\r
+ break;\r
+\r
+ case kEyeTVPluginSelector_ServiceChanged:\r
+ result = VLCEyeTVPluginServiceChanged((VLCEyeTVPluginGlobals_t*)params->refCon, \r
+ params->deviceID, params->serviceChanged.headendID, \r
+ params->serviceChanged.transponderID, params->serviceChanged.serviceID, \r
+ params->serviceChanged.pidList, params->serviceChanged.pidCount);\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
--- /dev/null
+/*****************************************************************************\r
+* eyetvplugin.h: Plug-In for the EyeTV software to connect to VLC\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
+#include "EyeTVPluginDefs.h"\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include <CoreFoundation/CoreFoundation.h>\r
+\r
+void VLCEyeTVPluginGlobalNotificationReceived( CFNotificationCenterRef center, \r
+ void *observer, \r
+ CFStringRef name, \r
+ const void *object, \r
+ CFDictionaryRef userInfo );
\ No newline at end of file
--- /dev/null
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; };
+ 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; };
+ CC09359B0AE11E6A00647FD0 /* eyetvplugin.c in Sources */ = {isa = PBXBuildFile; fileRef = CC09359A0AE11E6A00647FD0 /* eyetvplugin.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+ 8D576316048677EA00EA77CD /* VLC EyeTV Plug-In.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "VLC EyeTV Plug-In.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+ CC09359A0AE11E6A00647FD0 /* eyetvplugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = eyetvplugin.c; sourceTree = "<group>"; };
+ CC09359C0AE11E7900647FD0 /* EyeTVPluginDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EyeTVPluginDefs.h; sourceTree = "<group>"; };
+ CC3AE2920AE2E4EE00ACC87C /* eyetvplugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eyetvplugin.h; sourceTree = "<group>"; };
+ CC74BC500AE2714300AD738B /* eyetv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eyetv.c; path = ../../../modules/access/eyetv.c; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D576313048677EA00EA77CD /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 089C166AFE841209C02AAC07 /* VLC EyeTV Plug-In */ = {
+ isa = PBXGroup;
+ children = (
+ CC74BC530AE2715100AD738B /* access module */,
+ 08FB77AFFE84173DC02AAC07 /* Source */,
+ 089C167CFE841241C02AAC07 /* Resources */,
+ 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */,
+ 19C28FB6FE9D52B211CA2CBB /* Products */,
+ );
+ name = "VLC EyeTV Plug-In";
+ sourceTree = "<group>";
+ };
+ 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */,
+ );
+ name = "External Frameworks and Libraries";
+ sourceTree = "<group>";
+ };
+ 089C167CFE841241C02AAC07 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D576317048677EA00EA77CD /* Info.plist */,
+ 8D5B49A704867FD3000E48DA /* InfoPlist.strings */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 08FB77AFFE84173DC02AAC07 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ CC3AE2920AE2E4EE00ACC87C /* eyetvplugin.h */,
+ CC09359A0AE11E6A00647FD0 /* eyetvplugin.c */,
+ CC09359C0AE11E7900647FD0 /* EyeTVPluginDefs.h */,
+ );
+ name = Source;
+ sourceTree = "<group>";
+ };
+ 19C28FB6FE9D52B211CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D576316048677EA00EA77CD /* VLC EyeTV Plug-In.bundle */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ CC74BC530AE2715100AD738B /* access module */ = {
+ isa = PBXGroup;
+ children = (
+ CC74BC500AE2714300AD738B /* eyetv.c */,
+ );
+ name = "access module";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D57630D048677EA00EA77CD /* VLC EyeTV Plug-In */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "VLC EyeTV Plug-In" */;
+ buildPhases = (
+ 8D57630F048677EA00EA77CD /* Resources */,
+ 8D576311048677EA00EA77CD /* Sources */,
+ 8D576313048677EA00EA77CD /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "VLC EyeTV Plug-In";
+ productInstallPath = "$(HOME)/Library/Bundles";
+ productName = "VLC EyeTV Plug-In";
+ productReference = 8D576316048677EA00EA77CD /* VLC EyeTV Plug-In.bundle */;
+ productType = "com.apple.product-type.bundle";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 089C1669FE841209C02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "eyetvplugin" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = 089C166AFE841209C02AAC07 /* VLC EyeTV Plug-In */;
+ projectDirPath = "";
+ projectRoot = "";
+ shouldCheckCompatibility = 1;
+ targets = (
+ 8D57630D048677EA00EA77CD /* VLC EyeTV Plug-In */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D57630F048677EA00EA77CD /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D576311048677EA00EA77CD /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ CC09359B0AE11E6A00647FD0 /* eyetvplugin.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C167EFE841241C02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB911B08733D790010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = "compiler-default";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Library/Bundles";
+ PRODUCT_NAME = "VLC EyeTV Plug-In";
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = YES;
+ };
+ name = Debug;
+ };
+ 1DEB911C08733D790010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ ppc,
+ i386,
+ );
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ INFOPLIST_FILE = Info.plist;
+ INSTALL_PATH = "$(HOME)/Library/Bundles";
+ PRODUCT_NAME = "VLC EyeTV Plug-In";
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Release;
+ };
+ 1DEB911F08733D790010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Debug;
+ };
+ 1DEB912008733D790010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "VLC EyeTV Plug-In" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB911B08733D790010E9CD /* Debug */,
+ 1DEB911C08733D790010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "eyetvplugin" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB911F08733D790010E9CD /* Debug */,
+ 1DEB912008733D790010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
SOURCES_access_ftp = ftp.c
SOURCES_access_smb = smb.c
SOURCES_access_gnomevfs = gnomevfs.c
+SOURCES_access_eyetv = eyetv.c
SOURCES_dvdnav = dvdnav.c
SOURCES_dvdread = dvdread.c
SOURCES_dc1394 = dc1394.c
--- /dev/null
+/*****************************************************************************\r
+ * eyetv.c : Access module to connect to our plugin running within EyeTV\r
+ *****************************************************************************\r
+ * Copyright (C) 2006-2007 the VideoLAN team\r
+ * $Id$\r
+ *\r
+ * Author: 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
+/*****************************************************************************\r
+ * Preamble\r
+ *****************************************************************************/\r
+#include <stdlib.h>\r
+\r
+#include <vlc/vlc.h>\r
+#include <vlc_access.h>\r
+\r
+#include <CoreFoundation/CoreFoundation.h>\r
+\r
+/* TODO:\r
+ * watch for PluginQuit or DeviceRemoved to stop output to VLC's core then */\r
+\r
+/*****************************************************************************\r
+ * Module descriptior\r
+ *****************************************************************************/\r
+static int Open ( vlc_object_t * );\r
+static void Close( vlc_object_t * );\r
+\r
+vlc_module_begin();\r
+ set_shortname( "EyeTV" );\r
+ set_description( _("EyeTV access module") );\r
+ set_category( CAT_INPUT );\r
+ set_subcategory( SUBCAT_INPUT_ACCESS );\r
+\r
+ set_capability( "access2", 0 );\r
+ add_shortcut( "eyetv" );\r
+ set_callbacks( Open, Close );\r
+vlc_module_end();\r
+\r
+/*****************************************************************************\r
+ * Access: local prototypes\r
+ *****************************************************************************/\r
+typedef struct\r
+{\r
+ VLC_COMMON_MEMBERS\r
+ \r
+ vlc_mutex_t lock;\r
+ vlc_cond_t wait;\r
+ \r
+ CFMessagePortRef inputMessagePortFromEyeTV;\r
+} eyetv_thread_t;\r
+\r
+struct access_sys_t\r
+{\r
+ eyetv_thread_t *p_thread;\r
+};\r
+\r
+CFDataRef dataFromEyetv;\r
+int lastPacketId;\r
+int lastForwardedPacketId;\r
+\r
+static int Read( access_t *, uint8_t *, int );\r
+static int Control( access_t *, int, va_list );\r
+static void Thread( vlc_object_t * );\r
+CFDataRef msgPortCallback( CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info );\r
+\r
+/*****************************************************************************\r
+ * Open: sets up the module and its threads\r
+ *****************************************************************************/\r
+static int Open( vlc_object_t *p_this )\r
+{\r
+ access_t *p_access = (access_t *)p_this;\r
+ access_sys_t *p_sys;\r
+ eyetv_thread_t *p_thread;\r
+ CFMessagePortContext context;\r
+ memset(&context, 0, sizeof(context)); \r
+ \r
+ /* Init p_access */\r
+ access_InitFields( p_access ); \\r
+ ACCESS_SET_CALLBACKS( Read, NULL, Control, NULL ); \\r
+ MALLOC_ERR( p_access->p_sys, access_sys_t ); \\r
+ p_sys = p_access->p_sys; memset( p_sys, 0, sizeof( access_sys_t ) );\r
+\r
+ msg_Dbg( p_access, "coming up" );\r
+\r
+ /* create receiving thread which will keep the message port alive without blocking */\r
+ p_sys->p_thread = p_thread = vlc_object_create( p_access, sizeof( eyetv_thread_t ) );\r
+ vlc_object_attach( p_thread, p_this );\r
+ vlc_mutex_init( p_access, &p_thread->lock );\r
+ vlc_cond_init( p_access, &p_thread->wait );\r
+ msg_Dbg( p_access, "thread created, msg port following now" );\r
+ \r
+ /* set up our own msg port\r
+ * we may give the msgport such a generic name, because EyeTV may only run\r
+ * once per entire machine, so we can't interfere with other instances.\r
+ * we just trust the user no to launch multiple VLC instances trying to \r
+ * access EyeTV at the same time. If this happens, the latest launched\r
+ * instance will win. */\r
+ p_sys->p_thread->inputMessagePortFromEyeTV = CFMessagePortCreateLocal( kCFAllocatorDefault,\r
+ CFSTR("VLCEyeTVMsgPort"),\r
+ &msgPortCallback,\r
+ &context,\r
+ /* no info to free */ NULL );\r
+ if( p_sys->p_thread->inputMessagePortFromEyeTV == NULL )\r
+ {\r
+ msg_Err( p_access, "opening local msg port failed" );\r
+ free( p_sys->p_thread->inputMessagePortFromEyeTV );\r
+ vlc_mutex_destroy( &p_thread->lock );\r
+ vlc_cond_destroy( &p_thread->wait );\r
+ vlc_object_detach( p_thread );\r
+ vlc_object_destroy( p_thread );\r
+ free( p_sys );\r
+ return VLC_EGENERIC;\r
+ }\r
+ else\r
+ msg_Dbg( p_access, "remote msg port opened" );\r
+ \r
+ /* let the thread run */\r
+ if( vlc_thread_create( p_thread, "EyeTV Receiver Thread", Thread,\r
+ VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )\r
+ {\r
+ msg_Err( p_access, "couldn't launch eyetv receiver thread" );\r
+ vlc_mutex_destroy( &p_thread->lock );\r
+ vlc_cond_destroy( &p_thread->wait );\r
+ vlc_object_detach( p_thread );\r
+ vlc_object_destroy( p_thread );\r
+ free( p_sys );\r
+ return VLC_EGENERIC;\r
+ }\r
+\r
+ msg_Dbg( p_access, "receiver thread created and launched" );\r
+ \r
+ /* tell the EyeTV plugin to open up its msg port and start sending */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter (),\r
+ CFSTR("VLCAccessStartDataSending"), \r
+ CFSTR("VLCEyeTVSupport"), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ \r
+ msg_Dbg( p_access, "plugin notified" );\r
+ \r
+ /* we don't need such a high priority */\r
+ //vlc_thread_set_priority( p_access, VLC_THREAD_PRIORITY_LOW );\r
+ \r
+ return VLC_SUCCESS;\r
+}\r
+\r
+/*****************************************************************************\r
+ * Close: closes msg-port, free resources\r
+ *****************************************************************************/\r
+static void Close( vlc_object_t *p_this )\r
+{\r
+ access_t *p_access = (access_t *)p_this;\r
+ access_sys_t *p_sys = p_access->p_sys;\r
+ \r
+ msg_Dbg( p_access, "closing" );\r
+ \r
+ /* tell the EyeTV plugin to close its msg port and stop sending */\r
+ CFNotificationCenterPostNotification( CFNotificationCenterGetDistributedCenter (),\r
+ CFSTR("VLCAccessStopDataSending"), \r
+ CFSTR("VLCEyeTVSupport"), \r
+ /*userInfo*/ NULL, \r
+ TRUE );\r
+ \r
+ msg_Dbg( p_access, "plugin notified" );\r
+ \r
+ /* stop receiver thread */\r
+ p_sys->p_thread->b_die = VLC_TRUE;\r
+ vlc_mutex_lock( &p_sys->p_thread->lock );\r
+ vlc_cond_signal( &p_sys->p_thread->wait );\r
+ vlc_mutex_unlock( &p_sys->p_thread->lock );\r
+ vlc_thread_join( p_sys->p_thread );\r
+ \r
+ /* close msg port */\r
+ CFMessagePortInvalidate( p_sys->p_thread->inputMessagePortFromEyeTV );\r
+ free( p_sys->p_thread->inputMessagePortFromEyeTV );\r
+ msg_Dbg( p_access, "msg port closed and freed" );\r
+ \r
+ /* free thread */\r
+ vlc_mutex_destroy( &p_sys->p_thread->lock );\r
+ vlc_cond_destroy( &p_sys->p_thread->wait );\r
+ vlc_object_detach( p_sys->p_thread );\r
+ vlc_object_destroy( p_sys->p_thread );\r
+ \r
+ free( p_sys );\r
+}\r
+\r
+static void Thread( vlc_object_t *p_this )\r
+{\r
+ eyetv_thread_t *p_thread= (eyetv_thread_t*)p_this;\r
+ CFRunLoopSourceRef runLoopSource;\r
+ \r
+ /* create our run loop source for the port and attach it to our current loop */\r
+ runLoopSource = CFMessagePortCreateRunLoopSource( kCFAllocatorDefault,\r
+ p_thread->inputMessagePortFromEyeTV,\r
+ 0 );\r
+ CFRunLoopAddSource( CFRunLoopGetCurrent(),\r
+ runLoopSource,\r
+ kCFRunLoopDefaultMode );\r
+ \r
+ CFRunLoopRun();\r
+}\r
+\r
+\r
+/*****************************************************************************\r
+* msgPortCallback: receives data from the EyeTV plugin\r
+*****************************************************************************/\r
+CFDataRef msgPortCallback( CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info )\r
+{\r
+ extern CFDataRef dataFromEyetv;\r
+ extern int lastPacketId;\r
+ \r
+ /* copy callback data to module data */\r
+ dataFromEyetv = CFDataCreateCopy( kCFAllocatorDefault, data );\r
+#if 0\r
+ printf( "packet %i contained %i bytes, forwarding %i bytes\n",\r
+ (int)msgid,\r
+ (int)CFDataGetLength( data ),\r
+ (int)CFDataGetLength( dataFromEyetv ) );\r
+#endif\r
+\r
+ lastPacketId = msgid;\r
+ \r
+ return NULL; /* we've got nothing to return */\r
+}\r
+\r
+/*****************************************************************************\r
+* Read: forwarding data from EyeTV plugin which was received above\r
+*****************************************************************************/\r
+static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )\r
+{\r
+ access_sys_t *p_sys = p_access->p_sys;\r
+ extern CFDataRef dataFromEyetv;\r
+ extern int lastPacketId;\r
+ extern int lastForwardedPacketId;\r
+ \r
+ /* wait for a new buffer before forwarding */\r
+ while( lastPacketId == lastForwardedPacketId && !p_access->b_die )\r
+ {\r
+ msleep( INPUT_ERROR_SLEEP );\r
+ }\r
+ \r
+ /* read data here, copy it to p_buffer, fill i_len with respective length\r
+ * and return info with i_read; i_read = 0 == EOF */\r
+ if( dataFromEyetv )\r
+ {\r
+ CFDataGetBytes( dataFromEyetv,\r
+ CFRangeMake( 0, CFDataGetLength( dataFromEyetv ) ),\r
+ (uint8_t *)p_buffer );\r
+ i_len = (int)CFDataGetLength( dataFromEyetv );\r
+#if 0\r
+ msg_Dbg( p_access, "%i bytes with id %i received in read function, pushing to core",\r
+ (int)CFDataGetLength( dataFromEyetv ), lastPacketId );\r
+#endif\r
+ lastForwardedPacketId = lastPacketId;\r
+ if( i_len == 0)\r
+ {\r
+ msg_Err( p_access, "you looosed!" );\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ if( p_access->b_die )\r
+ return 0;\r
+ \r
+ return i_len;\r
+}\r
+\r
+/*****************************************************************************\r
+ * Control:\r
+ *****************************************************************************/\r
+static int Control( access_t *p_access, int i_query, va_list args )\r
+{/*\r
+ vlc_bool_t *pb_bool;\r
+ int *pi_int;\r
+ int64_t *pi_64;\r
+ \r
+ switch( i_query )\r
+ {\r
+ * *\r
+ case ACCESS_SET_PAUSE_STATE:\r
+ * Nothing to do *\r
+ break;\r
+\r
+ case ACCESS_CAN_SEEK:\r
+ case ACCESS_CAN_FASTSEEK:\r
+ case ACCESS_CAN_PAUSE:\r
+ case ACCESS_CAN_CONTROL_PACE:\r
+ case ACCESS_GET_MTU:\r
+ case ACCESS_GET_PTS_DELAY: \r
+ case ACCESS_GET_TITLE_INFO:\r
+ case ACCESS_SET_TITLE:\r
+ case ACCESS_SET_SEEKPOINT:\r
+ case ACCESS_SET_PRIVATE_ID_STATE:\r
+ return VLC_EGENERIC;\r
+ \r
+ default:\r
+ msg_Warn( p_access, "unimplemented query in control" );\r
+ return VLC_EGENERIC;\r
+ \r
+ }\r
+ return VLC_SUCCESS;*/\r
+ return VLC_EGENERIC;\r
+}\r
fspanel.h \
update.h \
update.m \
+ eyetv.h \
+ eyetv.m \
$(NULL)
--- /dev/null
+/*****************************************************************************\r
+* eyetv.h: 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
+#import <Cocoa/Cocoa.h>\r
+\r
+\r
+@interface VLCEyeTVController : NSObject \r
+{\r
+ BOOL b_eyeTVactive;\r
+ BOOL b_deviceConnected;\r
+}\r
+- (void)globalNotificationReceived: (NSNotification *)theNotification;\r
+- (BOOL)isEyeTVrunning;\r
+- (BOOL)isDeviceConnected;\r
+- (void)launchEyeTV;\r
+- (void)switchChannelUp:(BOOL)b_yesOrNo;\r
+- (void)selectChannel:(int)theChannelNum;\r
+- (int)getNumberOfChannels;\r
+- (NSString *)getNameOfChannel:(int)theChannelNum;\r
+\r
+@end\r
--- /dev/null
+/*****************************************************************************\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
+#import "eyetv.h"
+/* for apple event interaction [carbon] */\r
+#import <ApplicationServices/ApplicationServices.h> \r
+/* 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
+ [[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
+ 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
id o_interaction_list; /* VLCInteractionList*/
id o_sfilters; /* VLCsFilters */
id o_update; /* VLCUpdate */
+ id o_eyetv; /* VLCEyeTVController */
BOOL nib_main_loaded; /* reference to the main-nib */
BOOL nib_open_loaded; /* reference to the open-nib */
BOOL nib_about_loaded; /* reference to the about-nib */
- (id)getMainIntfPgbar;
- (id)getControllerWindow;
- (id)getVoutMenu;
+- (id)getEyeTVController;
- (void)applicationWillTerminate:(NSNotification *)notification;
- (NSString *)localizedString:(char *)psz;
- (char *)delocalizeString:(NSString *)psz;
#import "embeddedwindow.h"
#import "update.h"
#import "AppleRemote.h"
+#import "eyetv.h"
#import <vlc_input.h>
[o_remote setClickCountEnabledButtons: kRemoteButtonPlay];
[o_remote setDelegate: _o_sharedMainInstance];
+ o_eyetv = [[VLCEyeTVController alloc] init];
+
+ /* announce our launch to a potential eyetv plugin */
+ [[NSDistributedNotificationCenter defaultCenter] postNotificationName: @"VLCOSXGUIInit"
+ object: @"VLCEyeTVSupport"
+ userInfo: NULL
+ deliverImmediately: YES];
+
return _o_sharedMainInstance;
}
return o_vout_menu;
}
+- (id)getEyeTVController
+{
+ if( o_eyetv )
+ return o_eyetv;
+ return nil;
+}
+
- (void)manage
{
playlist_t * p_playlist;
if( o_interaction_list != nil )
[o_interaction_list release];
+ if( o_eyetv != nil )
+ [o_eyetv release];
+
if( o_img_pause_pressed != nil )
{
[o_img_pause_pressed release];
IBOutlet id o_btn_ok;
IBOutlet id o_btn_cancel;
+ IBOutlet id o_output_ckbox;
+ IBOutlet id o_sout_options;
+
+ /* open file */
IBOutlet id o_file_path;
IBOutlet id o_file_btn_browse;
IBOutlet id o_file_stream;
+ /* open disc */
IBOutlet id o_disc_type;
IBOutlet id o_disc_device;
IBOutlet id o_disc_device_lbl;
IBOutlet id o_disc_videots_btn_browse;
IBOutlet id o_disc_dvd_menus;
+ /* open network */
IBOutlet id o_net_mode;
IBOutlet id o_net_udp_port;
IBOutlet id o_net_udp_port_lbl;
IBOutlet id o_net_http_url_lbl;
IBOutlet id o_net_timeshift_ckbox;
+ /* open subtitle file */
IBOutlet id o_file_sub_ckbox;
IBOutlet id o_file_sub_btn_settings;
IBOutlet id o_file_sub_sheet;
IBOutlet id o_file_sub_font_box;
IBOutlet id o_file_sub_file_box;
- IBOutlet id o_output_ckbox;
- IBOutlet id o_sout_options;
+ /* open eyetv support */
+ IBOutlet id o_eyetv_tabView;
+ IBOutlet id o_eyetv_channels_pop;
+ IBOutlet id o_eyetv_currentChannel_lbl;
+ IBOutlet id o_eyetv_chn_status_txt;
+ IBOutlet id o_eyetv_chn_bgbar;
+ IBOutlet id o_eyetv_launchEyeTV_btn;
+ IBOutlet id o_eyetv_nextProgram_btn;
+ IBOutlet id o_eyetv_noDevice_lbl;
+ IBOutlet id o_eyetv_noDeviceLong_lbl;
+ IBOutlet id o_eyetv_noEyeTV_lbl;
+ IBOutlet id o_eyetv_noEyeTVLong_lbl;
+ IBOutlet id o_eyetv_previousProgram_btn;
BOOL b_autoplay;
}
- (IBAction)openNetStepperChanged:(id)sender;
- (void)openNetInfoChanged:(NSNotification *)o_notification;
+- (IBAction)eyetvSwitchChannel:(id)sender;
+- (IBAction)eyetvLaunch:(id)sender;
+- (void)eyetvChanged:(NSNotification *)o_notification;
+- (void)setupChannelInfo;
+
- (IBAction)subsChanged:(id)sender;
- (IBAction)subSettings:(id)sender;
- (IBAction)subFileBrowse:(id)sender;
/*****************************************************************************
* open.m: MacOS X module for vlc
*****************************************************************************
- * Copyright (C) 2002-2006 the VideoLAN team
+ * Copyright (C) 2002-2007 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
#include <IOKit/storage/IOCDMedia.h>
#include <IOKit/storage/IODVDMedia.h>
-#include "intf.h"
-#include "playlist.h"
-#include "open.h"
-#include "output.h"
-#import <vlc_interface.h>
+#import "intf.h"
+#import "playlist.h"
+#import "open.h"
+#import "output.h"
+#import "eyetv.h"
/*****************************************************************************
* GetEjectableMediaOfClass
[o_net_udp_port setIntValue: config_GetInt( p_intf, "server-port" )];
[o_net_udp_port_stp setIntValue: config_GetInt( p_intf, "server-port" )];
-
+
+ [o_eyetv_chn_bgbar setUsesThreadedAnimation: YES];
+ /* FIXME: implement EyeTV l10n here */
+
[self setSubPanel];
selector: @selector(openNetInfoChanged:)
name: NSControlTextDidChangeNotification
object: o_net_http_url];
+
+ /* wake up with the correct GUI */
+ if( [[[VLCMain sharedInstance] getEyeTVController] isEyeTVrunning] == YES )
+ [o_eyetv_tabView selectTabViewItemWithIdentifier:@"nodevice"];
+ if( [[[VLCMain sharedInstance] getEyeTVController] isDeviceConnected] == YES )
+ {
+ [o_eyetv_tabView selectTabViewItemWithIdentifier:@"eyetvup"];
+ [self setupChannelInfo];
+ }
+
+ [[NSDistributedNotificationCenter defaultCenter] addObserver: self
+ selector: @selector(eyetvChanged:)
+ name: NULL
+ object: @"VLCEyeTVSupport"
+ suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately];
/* register clicks on text fields */
[[NSNotificationCenter defaultCenter] addObserver: self
}
}
+- (IBAction)eyetvSwitchChannel:(id)sender
+{
+ if( sender == o_eyetv_nextProgram_btn )
+ [[[VLCMain sharedInstance] getEyeTVController] switchChannelUp: YES];
+ else if( sender == o_eyetv_previousProgram_btn )
+ [[[VLCMain sharedInstance] getEyeTVController] switchChannelUp: NO];
+ else if( sender == o_eyetv_channels_pop )
+ [[[VLCMain sharedInstance] getEyeTVController] selectChannel:
+ [sender indexOfSelectedItem]];
+ else
+ msg_Err( VLCIntf, "eyetvSwitchChannel sent by unknown object" );
+}
+
+- (IBAction)eyetvLaunch:(id)sender
+{
+ [[[VLCMain sharedInstance] getEyeTVController] launchEyeTV];
+}
+
+- (void)eyetvChanged:(NSNotification *)o_notification
+{
+ if( [[o_notification name] isEqualToString: @"DeviceAdded"] )
+ {
+ msg_Dbg( VLCIntf, "eyetv device was added" );
+ [o_eyetv_tabView selectTabViewItemWithIdentifier:@"eyetvup"];
+ [self setupChannelInfo];
+ }
+ else if( [[o_notification name] isEqualToString: @"DeviceRemoved"] )
+ {
+ /* leave the channel selection like that,
+ * switch to our "no device" tab */
+ msg_Dbg( VLCIntf, "eyetv device was removed" );
+ [o_eyetv_tabView selectTabViewItemWithIdentifier:@"nodevice"];
+ }
+ else if( [[o_notification name] isEqualToString: @"PluginQuit"] )
+ {
+ /* switch to the "launch eyetv" tab */
+ msg_Dbg( VLCIntf, "eyetv was terminated" );
+ [o_eyetv_tabView selectTabViewItemWithIdentifier:@"noeyetv"];
+ }
+ else if( [[o_notification name] isEqualToString: @"PluginInit"] )
+ {
+ /* we got no device yet */
+ msg_Dbg( VLCIntf, "eyetv was launched, no device yet" );
+ [o_eyetv_tabView selectTabViewItemWithIdentifier:@"nodevice"];
+ }
+ else
+ msg_Warn( VLCIntf, "unknown external notify '%s' received", [[o_notification name] UTF8String] );
+}
+
+/* little helper method, since this code needs to be run by multiple objects */
+- (void)setupChannelInfo
+{
+ /* set up channel selection */
+ [o_eyetv_channels_pop removeAllItems];
+ [o_eyetv_chn_bgbar setHidden: NO];
+ [o_eyetv_chn_bgbar animate: self];
+ [o_eyetv_chn_status_txt setStringValue: _NS("Retrieving Channel Info...")];
+ [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]
+ action: nil
+ keyEquivalent: @""];
+ x += 1;
+ }
+
+ /* clean up GUI */
+ [o_eyetv_chn_bgbar setHidden: YES];
+ [o_eyetv_chn_status_txt setHidden: YES];
+}
+
- (IBAction)subsChanged:(id)sender
{
if ([o_file_sub_ckbox state] == NSOnState)