From b576354894b6f2f989bd2d2eed8585d75984efe4 Mon Sep 17 00:00:00 2001 From: Pierre d'Herbemont <pdherbemont@videolan.org> Date: Wed, 29 Aug 2007 19:42:29 +0000 Subject: [PATCH] extra/MacOSX/Framework: Initial import of the Mac OS X Framework. --- .../Framework/Examples/test/Controller.h | 18 + .../Framework/Examples/test/Controller.m | 34 ++ .../test/English.lproj/InfoPlist.strings | Bin 0 -> 202 bytes .../English.lproj/MainMenu.nib/classes.nib | 14 + .../test/English.lproj/MainMenu.nib/info.nib | 22 ++ .../MainMenu.nib/keyedobjects.nib | Bin 0 -> 18973 bytes .../MacOSX/Framework/Examples/test/Info.plist | 28 ++ extras/MacOSX/Framework/Examples/test/main.m | 26 ++ .../test/test.xcodeproj/project.pbxproj | 302 +++++++++++++++ .../Framework/Examples/test/test_Prefix.pch | 7 + extras/MacOSX/Framework/Headers/VLC/VLC.h | 39 ++ .../MacOSX/Framework/Headers/VLC/VLCMedia.h | 56 +++ .../Headers/VLC/VLCMediaDiscoverer.h | 42 +++ .../Framework/Headers/VLC/VLCMediaLibrary.h | 42 +++ .../Framework/Headers/VLC/VLCPlaylist.h | 61 +++ .../Headers/VLC/VLCPlaylistDataSource.h | 62 +++ .../Headers/VLC/VLCServicesDiscoverer.h | 34 ++ extras/MacOSX/Framework/Headers/VLC/VLCTime.h | 35 ++ .../Framework/Headers/VLC/VLCVideoView.h | 100 +++++ .../Framework/Headers/VLCEventManager.h | 43 +++ extras/MacOSX/Framework/Headers/VLCLibrary.h | 68 ++++ extras/MacOSX/Framework/Makefile | 157 ++++++++ extras/MacOSX/Framework/Resources/Info.plist | 22 ++ .../MacOSX/Framework/Resources/version.plist | 12 + .../Framework/Sources/VLCEventManager.m | 218 +++++++++++ extras/MacOSX/Framework/Sources/VLCLibrary.m | 44 +++ extras/MacOSX/Framework/Sources/VLCMedia.m | 257 +++++++++++++ .../Framework/Sources/VLCMediaDiscoverer.m | 110 ++++++ .../Framework/Sources/VLCMediaLibrary.m | 87 +++++ extras/MacOSX/Framework/Sources/VLCPlaylist.m | 355 ++++++++++++++++++ .../Framework/Sources/VLCPlaylistDataSource.m | 178 +++++++++ .../Framework/Sources/VLCServicesDiscoverer.m | 60 +++ extras/MacOSX/Framework/Sources/VLCTime.m | 56 +++ .../MacOSX/Framework/Sources/VLCVideoView.m | 272 ++++++++++++++ extras/MacOSX/Framework/Sources/test.m | 13 + 35 files changed, 2874 insertions(+) create mode 100644 extras/MacOSX/Framework/Examples/test/Controller.h create mode 100644 extras/MacOSX/Framework/Examples/test/Controller.m create mode 100644 extras/MacOSX/Framework/Examples/test/English.lproj/InfoPlist.strings create mode 100644 extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/classes.nib create mode 100644 extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/info.nib create mode 100644 extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/keyedobjects.nib create mode 100644 extras/MacOSX/Framework/Examples/test/Info.plist create mode 100644 extras/MacOSX/Framework/Examples/test/main.m create mode 100644 extras/MacOSX/Framework/Examples/test/test.xcodeproj/project.pbxproj create mode 100644 extras/MacOSX/Framework/Examples/test/test_Prefix.pch create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLC.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCMedia.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCMediaDiscoverer.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCMediaLibrary.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCPlaylist.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCPlaylistDataSource.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCServicesDiscoverer.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCTime.h create mode 100644 extras/MacOSX/Framework/Headers/VLC/VLCVideoView.h create mode 100644 extras/MacOSX/Framework/Headers/VLCEventManager.h create mode 100644 extras/MacOSX/Framework/Headers/VLCLibrary.h create mode 100644 extras/MacOSX/Framework/Makefile create mode 100644 extras/MacOSX/Framework/Resources/Info.plist create mode 100644 extras/MacOSX/Framework/Resources/version.plist create mode 100644 extras/MacOSX/Framework/Sources/VLCEventManager.m create mode 100644 extras/MacOSX/Framework/Sources/VLCLibrary.m create mode 100644 extras/MacOSX/Framework/Sources/VLCMedia.m create mode 100644 extras/MacOSX/Framework/Sources/VLCMediaDiscoverer.m create mode 100644 extras/MacOSX/Framework/Sources/VLCMediaLibrary.m create mode 100644 extras/MacOSX/Framework/Sources/VLCPlaylist.m create mode 100644 extras/MacOSX/Framework/Sources/VLCPlaylistDataSource.m create mode 100644 extras/MacOSX/Framework/Sources/VLCServicesDiscoverer.m create mode 100644 extras/MacOSX/Framework/Sources/VLCTime.m create mode 100644 extras/MacOSX/Framework/Sources/VLCVideoView.m create mode 100644 extras/MacOSX/Framework/Sources/test.m diff --git a/extras/MacOSX/Framework/Examples/test/Controller.h b/extras/MacOSX/Framework/Examples/test/Controller.h new file mode 100644 index 000000000000..c789867981cc --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/Controller.h @@ -0,0 +1,18 @@ +/* Controller */ + +#import <Cocoa/Cocoa.h> +#import <VLC/VLC.h> + +@interface Controller : NSObject +{ + IBOutlet id window; + IBOutlet id playlistOutline; + IBOutlet id videoHolderView; + + VLCVideoView * videoView; + VLCPlaylist * playlist; +} +- (void)awakeFromNib; + +- (void)play:(id)sender; +@end diff --git a/extras/MacOSX/Framework/Examples/test/Controller.m b/extras/MacOSX/Framework/Examples/test/Controller.m new file mode 100644 index 000000000000..544bc19536c6 --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/Controller.m @@ -0,0 +1,34 @@ +#import "Controller.h" + +@implementation Controller +- (void)awakeFromNib +{ + NSRect rect; + VLCPlaylistDataSource * aDataSource; + + /* Won't be released */ + videoView = [[VLCVideoView alloc] init]; + + rect = [videoHolderView frame]; + [[window contentView] replaceSubview: videoHolderView with: videoView]; + [videoView setFrame: rect]; + [videoView setAutoresizingMask: NSViewHeightSizable|NSViewWidthSizable]; + + /* Won't be released */ + playlist = [[VLCPlaylist alloc] init]; + + /* Won't be released */ + aDataSource = [[VLCPlaylistDataSource alloc] initWithPlaylist:playlist videoView:videoView]; + + [playlistOutline setDataSource: aDataSource]; + [playlistOutline registerForDraggedTypes: [NSArray arrayWithObjects:NSFilenamesPboardType, NSURLPboardType, nil]]; +} + +- (void)play:(id)sender +{ + if(![videoView playlist]) + [videoView setPlaylist: playlist]; + if( [sender isKindOfClass:[NSTableView class]] && [sender selectedRow] >= 0) + [videoView playItemAtIndex: [sender selectedRow]]; +} +@end diff --git a/extras/MacOSX/Framework/Examples/test/English.lproj/InfoPlist.strings b/extras/MacOSX/Framework/Examples/test/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..997688e2fd53fd8d44166a1895730ea43ed42f47 GIT binary patch literal 202 zcmW-ZOAf&R6h+V2DjLH^R7?!S$b<v~79d57&`(+<wIiFvY4eizx%a;F`$mKWtSC4V zbLYyNgp=CKSy8JL<j%mE+LvCb`;fBB*F02jrkgGm64A3Z>{#$5lbf^EkLAW3{7RTh oDE+A9pSg65nVdc!``%jXwyDfqOK2p<UP<Q;OpO^?6Mv@s0X&N%;s5{u literal 0 HcmV?d00001 diff --git a/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/classes.nib b/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/classes.nib new file mode 100644 index 000000000000..6df89f0e7a81 --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/classes.nib @@ -0,0 +1,14 @@ +{ + IBClasses = ( + { + ACTIONS = {play = id; }; + CLASS = Controller; + LANGUAGE = ObjC; + OUTLETS = {playlistOutline = id; videoHolderView = id; window = id; }; + SUPERCLASS = NSObject; + }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + {CLASS = NSSegmentedControl; LANGUAGE = ObjC; SUPERCLASS = NSControl; } + ); + IBVersion = 1; +} \ No newline at end of file diff --git a/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/info.nib b/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/info.nib new file mode 100644 index 000000000000..7150bdf32a4d --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/info.nib @@ -0,0 +1,22 @@ +<?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>IBDocumentLocation</key> + <string>135 107 356 240 0 0 1680 1028 </string> + <key>IBEditorPositions</key> + <dict> + <key>29</key> + <string>132 353 338 44 0 0 1680 1028 </string> + </dict> + <key>IBFramework Version</key> + <string>446.1</string> + <key>IBOpenObjects</key> + <array> + <integer>21</integer> + <integer>29</integer> + </array> + <key>IBSystem Version</key> + <string>8R218</string> +</dict> +</plist> diff --git a/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/keyedobjects.nib b/extras/MacOSX/Framework/Examples/test/English.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..0f165c1900539286c27e58d8aad3f7134a0298bd GIT binary patch literal 18973 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⋘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 ZRaQ<`7o_}9^1H6^qi*Z_uKAzk`9D{6em(#I literal 0 HcmV?d00001 diff --git a/extras/MacOSX/Framework/Examples/test/Info.plist b/extras/MacOSX/Framework/Examples/test/Info.plist new file mode 100644 index 000000000000..cf9cf810a54e --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/Info.plist @@ -0,0 +1,28 @@ +<?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>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string>com.yourcompany.test</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/extras/MacOSX/Framework/Examples/test/main.m b/extras/MacOSX/Framework/Examples/test/main.m new file mode 100644 index 000000000000..9ed4accd2fde --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/main.m @@ -0,0 +1,26 @@ +// +// main.m +// test +// +// Created by Pierre d'Herbemont on 13/04/07. +// Copyright __MyCompanyName__ 2007. All rights reserved. +// + +#import <Cocoa/Cocoa.h> +#import <VLC/VLC.h> +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + /* If we can't load the VLC.framework dyld will tell us anyway + * But this is cool */ + if(test_vlc_framework() == 0xbabe) + printf("We are linked to VLC.framework!\n"); + else + { + fprintf(stderr, "*** Can't load the VLC.framework\n"); + return -1; + } + + return NSApplicationMain(argc, (const char **) argv); +} diff --git a/extras/MacOSX/Framework/Examples/test/test.xcodeproj/project.pbxproj b/extras/MacOSX/Framework/Examples/test/test.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..bab3fe90e861 --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/test.xcodeproj/project.pbxproj @@ -0,0 +1,302 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 630AFC550BCFD65300802A4E /* VLC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 630AFC540BCFD65300802A4E /* VLC.framework */; }; + 6333027A0BD24CDB00193D7D /* Controller.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 633302780BD24CDB00193D7D /* Controller.h */; }; + 6333027B0BD24CDB00193D7D /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 633302790BD24CDB00193D7D /* Controller.m */; }; + 6333039B0BD2553F00193D7D /* VLC.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 630AFC540BCFD65300802A4E /* VLC.framework */; }; + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; + 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 630AFC670BCFD81B00802A4E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 6333039B0BD2553F00193D7D /* VLC.framework in CopyFiles */, + 6333027A0BD24CDB00193D7D /* Controller.h in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; + 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; }; + 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; + 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; + 32CA4F630368D1EE00C91783 /* test_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_Prefix.pch; sourceTree = "<group>"; }; + 630AFC540BCFD65300802A4E /* VLC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VLC.framework; path = ../../VLC.framework; sourceTree = SOURCE_ROOT; }; + 633302780BD24CDB00193D7D /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = "<group>"; }; + 633302790BD24CDB00193D7D /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = "<group>"; }; + 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; + 8D1107320486CEB800E47090 /* test.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = test.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D11072E0486CEB800E47090 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, + 630AFC550BCFD65300802A4E /* VLC.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 633302780BD24CDB00193D7D /* Controller.h */, + 633302790BD24CDB00193D7D /* Controller.m */, + ); + name = Classes; + sourceTree = "<group>"; + }; + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 630AFC540BCFD65300802A4E /* VLC.framework */, + 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, + ); + name = "Linked Frameworks"; + sourceTree = "<group>"; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 29B97324FDCFA39411CA2CEA /* AppKit.framework */, + 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, + 29B97325FDCFA39411CA2CEA /* Foundation.framework */, + ); + name = "Other Frameworks"; + sourceTree = "<group>"; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D1107320486CEB800E47090 /* test.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + 29B97314FDCFA39411CA2CEA /* test */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = test; + sourceTree = "<group>"; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* test_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = "<group>"; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8D1107310486CEB800E47090 /* Info.plist */, + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, + ); + name = Resources; + sourceTree = "<group>"; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D1107260486CEB800E47090 /* test */ = { + isa = PBXNativeTarget; + buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "test" */; + buildPhases = ( + 8D1107290486CEB800E47090 /* Resources */, + 630AFC670BCFD81B00802A4E /* CopyFiles */, + 8D11072C0486CEB800E47090 /* Sources */, + 8D11072E0486CEB800E47090 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = test; + productInstallPath = "$(HOME)/Applications"; + productName = test; + productReference = 8D1107320486CEB800E47090 /* test.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "test" */; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* test */; + projectDirPath = ""; + targets = ( + 8D1107260486CEB800E47090 /* test */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D1107290486CEB800E47090 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, + 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D11072C0486CEB800E47090 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D11072D0486CEB800E47090 /* main.m in Sources */, + 6333027B0BD24CDB00193D7D /* Controller.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C165DFE840E0CC02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = "<group>"; + }; + 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { + isa = PBXVariantGroup; + children = ( + 29B97319FDCFA39411CA2CEA /* English */, + ); + name = MainMenu.nib; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + C01FCF4B08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../..\""; + 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)/Applications"; + PRODUCT_NAME = test; + WRAPPER_EXTENSION = app; + ZERO_LINK = YES; + }; + name = Debug; + }; + C01FCF4C08A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../..\""; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + PRODUCT_NAME = test; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(NATIVE_ARCH)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4B08A954540054247B /* Debug */, + C01FCF4C08A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/extras/MacOSX/Framework/Examples/test/test_Prefix.pch b/extras/MacOSX/Framework/Examples/test/test_Prefix.pch new file mode 100644 index 000000000000..0b05af766f3d --- /dev/null +++ b/extras/MacOSX/Framework/Examples/test/test_Prefix.pch @@ -0,0 +1,7 @@ +// +// Prefix header for all source files of the 'test' target in the 'test' project +// + +#ifdef __OBJC__ + #import <Cocoa/Cocoa.h> +#endif diff --git a/extras/MacOSX/Framework/Headers/VLC/VLC.h b/extras/MacOSX/Framework/Headers/VLC/VLC.h new file mode 100644 index 000000000000..f28e8f76a71a --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLC.h @@ -0,0 +1,39 @@ +/***************************************************************************** + * VLC.h: VLC.framework main header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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. + *****************************************************************************/ + +#ifndef VLC_FRAMEWORK_VLC_H +#define VLC_FRAMEWORK_VLC_H + +typedef void * _opaque_ptr; + +#import <VLC/VLCMedia.h> +#import <VLC/VLCMediaDiscoverer.h> +#import <VLC/VLCMediaLibrary.h> +#import <VLC/VLCPlaylist.h> +#import <VLC/VLCPlaylistDataSource.h> +#import <VLC/VLCServicesDiscoverer.h> +#import <VLC/VLCTime.h> +#import <VLC/VLCVideoView.h> + +#endif /* VLC_FRAMEWORK_VLC_H */ diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCMedia.h b/extras/MacOSX/Framework/Headers/VLC/VLCMedia.h new file mode 100644 index 000000000000..eb73cd4fb9e1 --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCMedia.h @@ -0,0 +1,56 @@ +/***************************************************************************** + * VLCMedia.h: VLC.framework VLCMedia header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCPlaylist.h> + +/* Meta */ +extern NSString * VLCMetaInformationTitle; /* Associated to an NSString */ +extern NSString * VLCMetaInformationAuthor; /* Associated to an NSString */ +extern NSString * VLCMetaInformationArtwork; /* Associated to an NSImage */ + +/* Notification */ +extern NSString * VLCMediaSubItemAdded; + +@class VLCPlaylist; + +@interface VLCMedia : NSObject +{ + void * md; + NSString * url; + VLCPlaylist *subitems; + NSMutableDictionary *metaInformation; +} + +- (id)initWithURL:(NSString *)anURL; ++ (id)mediaWithURL:(NSString *)anURL; + +- (void) dealloc; + +- (NSString *)url; +- (VLCPlaylist *)subitems; + +/* Returns a dictionary with corresponding object associated with a meta */ +- (NSDictionary *)metaInformation; +@end diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCMediaDiscoverer.h b/extras/MacOSX/Framework/Headers/VLC/VLCMediaDiscoverer.h new file mode 100644 index 000000000000..e9ead09c146c --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCMediaDiscoverer.h @@ -0,0 +1,42 @@ +/***************************************************************************** + * VLCMediaDiscoverer.h: VLC.framework VLCMediaDiscoverer header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCPlaylist.h> + +@class VLCPlaylist; + +@interface VLCMediaDiscoverer : NSObject +{ + NSString *localizedName; + VLCPlaylist * playlist; + void * mdis; +} + +- (id)initWithName:(NSString *)aServiceName; + +- (VLCPlaylist *)playlist; + +- (NSString *)localizedName; +@end diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCMediaLibrary.h b/extras/MacOSX/Framework/Headers/VLC/VLCMediaLibrary.h new file mode 100644 index 000000000000..2ff763848725 --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCMediaLibrary.h @@ -0,0 +1,42 @@ +/***************************************************************************** + * VLCMediaDiscoverer.h: VLC.framework VLCMediaDiscoverer header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCPlaylist.h> + +@class VLCPlaylist; + +@interface VLCMediaLibrary : NSObject +{ + VLCPlaylist * allMedia; + void * mlib; +} + ++ (id)sharedMediaLibrary; + +- (VLCPlaylist *)allMedia; + +- (NSArray *) playlists; + +@end diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCPlaylist.h b/extras/MacOSX/Framework/Headers/VLC/VLCPlaylist.h new file mode 100644 index 000000000000..0b409254777e --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCPlaylist.h @@ -0,0 +1,61 @@ +/***************************************************************************** + * VLCPlaylist.h: VLC.framework VLCPlaylist header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Foundation/Foundation.h> + +#import <VLC/VLCMedia.h> + +/* Hack to avoid troubles with modules/macosx for now */ +#define VLCPlaylist VLCPlaylistBis + +/* Notification Posted */ +extern NSString * VLCPlaylistItemChanged; +extern NSString * VLCPlaylistItemDeleted; +extern NSString * VLCPlaylistItemAdded; + +@class VLCMedia; + +@interface VLCPlaylist : NSObject +{ + NSMutableArray * items; + void * p_mlist; +} +- (id)init; + +- (void)lock; +- (void)unlock; + +- (VLCMedia *)mediaAtIndex: (int)index; +- (int)countMedia; + +- (NSArray *)sublists; +- (VLCPlaylist *)flatPlaylist; + +- (VLCMedia *)providerMedia; + +- (void)addMedia: (VLCMedia *)item; +- (void)insertMedia: (VLCMedia *)item atIndex: (int)index; +- (void)removeMediaAtIndex: (int)index; +@end + diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCPlaylistDataSource.h b/extras/MacOSX/Framework/Headers/VLC/VLCPlaylistDataSource.h new file mode 100644 index 000000000000..67c0ef82e4df --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCPlaylistDataSource.h @@ -0,0 +1,62 @@ +/***************************************************************************** + * VLCPlaylistDataSource.h: VLC.framework VLCPlaylistDataSource header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <VLC/VLCPlaylist.h> +#import <VLC/VLCVideoView.h> + +/* This class can be used as a data source for an NSOutlineView + * it will display the playlist content. If provided the videoView + * will automatically be associated to the given playlist, and actions + * in the outlineView will trigger the videoView, visual feedback of the + * current item in the videoview will be displayed in the outlineview + */ +@interface VLCPlaylistDataSource : NSObject +{ + VLCPlaylist * playlist; + VLCVideoView * videoView; + + NSOutlineView *outlineView; +} +- (id)initWithPlaylist:(VLCPlaylist *)aPlaylist; +- (id)initWithPlaylist:(VLCPlaylist *)aPlaylist videoView:(VLCVideoView *)aVideoView; + +- (VLCPlaylist *)playlist; +- (VLCVideoView *)videoView; +@end + +/* It could be really useful to use that, this probably need to be reviewed to see + * if it really belongs here */ +@interface VLCPlaylistDataSource (OutlineViewDataSource) +- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item; +- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item; +- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item; +- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item; +@end + +@interface VLCPlaylistDataSource (OutlineViewDataSourceDropping) +- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index; +- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index; +@end + + diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCServicesDiscoverer.h b/extras/MacOSX/Framework/Headers/VLC/VLCServicesDiscoverer.h new file mode 100644 index 000000000000..ebd439b0e48f --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCServicesDiscoverer.h @@ -0,0 +1,34 @@ +/***************************************************************************** + * VLCMediaDiscoverer.h: VLC.framework VLCMediaDiscoverer header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> + +@interface VLCServicesDiscoverer : NSObject +{ + NSArray * services; +} ++ (id)sharedDiscoverer; +- (id)init; +- (NSArray *)services; +@end diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCTime.h b/extras/MacOSX/Framework/Headers/VLC/VLCTime.h new file mode 100644 index 000000000000..0c16246448e6 --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCTime.h @@ -0,0 +1,35 @@ +/***************************************************************************** + * VLCTime.h: VLC.framework VLCTime header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> + +@interface VLCTime : NSObject +{ + NSNumber * value; +} +- (id)initWithNumber:(NSNumber *)aNumber; + +- (NSNumber *)numberRepresentation; +- (NSString *)stringRepresentation; +@end diff --git a/extras/MacOSX/Framework/Headers/VLC/VLCVideoView.h b/extras/MacOSX/Framework/Headers/VLC/VLCVideoView.h new file mode 100644 index 000000000000..e362c3266916 --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLC/VLCVideoView.h @@ -0,0 +1,100 @@ +/***************************************************************************** + * VLCVideoView.h: VLC.framework VLCVideoView header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> + +#import <VLC/VLCTime.h> +#import <VLC/VLCPlaylist.h> + +@protocol VLCVideoViewDelegate; + +/* Notification */ +extern NSString * VLCVideoDidChangeVolume; +extern NSString * VLCVideoDidChangeTime; +extern NSString * VLCVideoDidChangeCurrentlyPlayingItem; +extern NSString * VLCVideoDidStop; +extern NSString * VLCVideoDidPause; +extern NSString * VLCVideoDidPlay; + +@interface VLCVideoView : NSView +{ + VLCPlaylist * playlist; + NSConnection * connection; + id delegate; + BOOL stretchVideo; + + void * p_mi; + void * p_mlp; +} + +- (id)initWithFrame:(NSRect)frameRect; +- (void)dealloc; + +- (void)setPlaylist: (VLCPlaylist *)newPlaylist; +- (VLCPlaylist *)playlist; + +/* Play */ +- (void)play; +- (void)playItemAtIndex:(int)index; +- (void)playMedia:(VLCMedia *)media; +- (void)pause; +- (void)setCurrentTime:(VLCTime *)timeObj; + +/* State */ +- (BOOL)isPlaying; +- (BOOL)isPaused; +- (VLCTime *)currentTime; +- (id)currentPlaylistItem; + +/* Video output property */ +- (void)setStretchesVideo:(BOOL)flag; +- (BOOL)stretchesVideo; + +/* Fullscreen */ +- (void)enterFullscreen; +- (void)leaveFullscreen; + +/* Delegate */ +- (void)setDelegate: (id)newDelegate; +- (id)delegate; +@end + +@protocol VLCVideoViewDelegate +- (void)videoDidStop:(NSNotification *)notification; +- (void)videoDidPlay:(NSNotification *)notification; +- (void)videoDidPause:(NSNotification *)notification; +- (void)videoDidPlayNextPlaylistElement:(NSNotification *)notification; + +- (void)videoDidChangeVolume:(NSNotification *)notification; + +/* Returns NO if the Video shouldn't be paused */ +- (BOOL)videoWillPause:(NSNotification *)notification; +/* Returns NO if the Video shouldn't play next playlist element */ +- (BOOL)videoWillPlayNextPlaylistElement:(NSNotification *)notification; + +/* Posted when the progress of the video has reached a new step + * (every second?). + * The -object contained in the notification is the new VLCTime */ +- (void)videoDidChangeTime:(NSNotification *)notification; +@end diff --git a/extras/MacOSX/Framework/Headers/VLCEventManager.h b/extras/MacOSX/Framework/Headers/VLCEventManager.h new file mode 100644 index 000000000000..3fe6b9f90bb8 --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLCEventManager.h @@ -0,0 +1,43 @@ +/***************************************************************************** + * VLCEventManager.h: VLC.framework VLCEventManager header + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <pthread.h> + +/* This object is here to ensure safe inter thread communication */ + +@interface VLCEventManager : NSObject +{ + NSMutableArray * messageQueue; + pthread_t dispatcherThread; + pthread_mutex_t queueLock; + pthread_cond_t signalData; +} + +/* Return the default manager */ ++ (id)sharedManager; + +- (void)callOnMainThreadDelegateOfObject:(id)aTarget withDelegateMethod:(SEL)aSelector withNotificationName:(NSString *)aNotificationName; +- (void)callOnMainThreadObject:(id)aTarget withMethod:(SEL)aSelector withArgumentAsObject: (id)arg; +@end diff --git a/extras/MacOSX/Framework/Headers/VLCLibrary.h b/extras/MacOSX/Framework/Headers/VLCLibrary.h new file mode 100644 index 000000000000..b49d046c174c --- /dev/null +++ b/extras/MacOSX/Framework/Headers/VLCLibrary.h @@ -0,0 +1,68 @@ +/***************************************************************************** + * VLCLibrary.h: VLC.framework VLCLibrary implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> + +#include <vlc/libvlc.h> +#include <vlc/libvlc_structures.h> + +#import <VLC/VLCPlaylist.h> + +/* + * VLCLibrary object + */ + +@interface VLCLibrary : NSObject ++ (libvlc_instance_t *)sharedInstance; +@end + +/* + * Utility function + */ +#define quit_on_exception( ex ) __quit_on_exception( ex, __FUNCTION__, __FILE__, __LINE__ ) +static inline void __quit_on_exception( libvlc_exception_t * ex, const char * function, const char * file, int line_number ) +{ + if (libvlc_exception_raised( ex )) + { + /* XXX: localization */ + NSRunCriticalAlertPanel( @"Error", [NSString stringWithFormat:@"libvlc has thrown us an error: %s (%s:%d %s)", libvlc_exception_get_message(ex), file, line_number, function], @"Quit", nil, nil ); + exit( ex->i_code ); + } +} + +/* + * LibVLCBridging category + */ + +@interface VLCPlaylist (LibVLCBridging) ++ (id) playlistWithLibVLCMediaList: (libvlc_media_list_t *)p_new_mlist; +- (libvlc_media_list_t *) libVLCMediaList; +@end + +@interface VLCMedia (LibVLCBridging) +- (id) initWithLibVLCMediaDescriptor: (libvlc_media_descriptor_t *)p_md; ++ (id) mediaWithLibVLCMediaDescriptor: (libvlc_media_descriptor_t *)p_md; +- (libvlc_media_descriptor_t *) libVLCMediaDescriptor; +@end diff --git a/extras/MacOSX/Framework/Makefile b/extras/MacOSX/Framework/Makefile new file mode 100644 index 000000000000..82b010e2b6e7 --- /dev/null +++ b/extras/MacOSX/Framework/Makefile @@ -0,0 +1,157 @@ +CC=gcc +CFLAGS=-g -O2 +OBJCFLAGS=-fobjc-exceptions +LDFLAGS=-single_module -read_only_relocs suppress + +# We should set this properly. +srcdir=../../.. +LIBVLC=$(srcdir)/src/.libs/libvlc.1.dylib $(srcdir)/src/.libs/libvlc-control.0.dylib +LIBVLC_HEADERS=$(srcdir)/include +VLCCONFIG=$(srcdir)/vlc-config + +MODULES = $(patsubst %,$(SRC_DIR)/%,$(_MODULES)) + +HEADERS_DIR = Headers + +_EXPORTED_HEADERS= \ + VLC/VLC.h \ + VLC/VLCMedia.h \ + VLC/VLCMediaDiscoverer.h \ + VLC/VLCMediaLibrary.h \ + VLC/VLCPlaylist.h \ + VLC/VLCPlaylistDataSource.h \ + VLC/VLCServicesDiscoverer.h \ + VLC/VLCTime.h \ + VLC/VLCVideoView.h + +EXPORTED_HEADERS = $(patsubst %,$(HEADERS_DIR)/%,$(_EXPORTED_HEADERS)) + +EXPORTED_RESOURCES= \ + Resources/Info.plist \ + Resources/version.plist + +SRC_DIR = Sources + +_SRC = \ + test.m \ + VLCEventManager.m \ + VLCLibrary.m \ + VLCMedia.m \ + VLCMediaLibrary.m \ + VLCMediaDiscoverer.m \ + VLCPlaylist.m \ + VLCPlaylistDataSource.m \ + VLCServicesDiscoverer.m \ + VLCTime.m \ + VLCVideoView.m + +SRC = $(patsubst %,$(SRC_DIR)/%,$(_SRC)) + +HEADERS = $(EXPORTED_HEADERS) + +INCLUDES= -I . -I $(LIBVLC_HEADERS) -I $(HEADERS_DIR) + +FRAMEWORKS= -framework Cocoa + +OBJECTS=$(SRC:.m=.o) + +all: VLC.framework + +$(OBJECTS): $(HEADERS) + +.m.o: $< + $(CC) -c $(CFLAGS) $(OBJCFLAGS) $(INCLUDES) $< -o $@ + +DIR = VLC.framework \ + VLC.framework/Version/Current/Framework \ + VLC.framework/Version/Current/Headers \ + +VLC.framework/lib/libvlc.dylib: $(srcdir)/src/.libs/libvlc.dylib VLC.framework/lib + cp -f $(srcdir)/src/.libs/libvlc.1.dylib VLC.framework/lib/libvlc.dylib && \ + install_name_tool -id `pwd`/VLC.framework/lib/libvlc.1.dylib \ + VLC.framework/lib/libvlc.dylib + +VLC.framework/lib/libvlc-control.dylib: $(srcdir)/src/.libs/libvlc-control.dylib VLC.framework/lib + mkdir -p VLC.framework/Version/Current/lib && \ + cp -f $< $@ && \ + install_name_tool -id `pwd`/$@ $@ && \ + install_name_tool -change /usr/local/lib/libvlc.1.dylib \ + `pwd`/VLC.framework/lib/libvlc.dylib $@ + + +VLC.framework/Headers: $(HEADERS) + mkdir -p VLC.framework/Version/Current/Headers && \ + cp -f $(EXPORTED_HEADERS) VLC.framework/Version/Current/Headers && \ + ln -sf Version/Current/Headers VLC.framework + +VLC.framework/Resources: + mkdir -p VLC.framework/Version/Current/Resources && \ + cp -f $(EXPORTED_RESOURCES) VLC.framework/Version/Current/Resources && \ + ln -sf Version/Current/Resources VLC.framework + + +VLC.framework/modules: + /usr/bin/install -c -d ./VLC.framework/Version/Current/modules && \ + for i in `top_builddir="$(srcdir)" $(VLCCONFIG) --target plugin` ; do \ + if test -n "$$i" ; \ + then \ + cp "`pwd`/`dirname $$i`/.libs/`basename $$i`.dylib" \ + "./VLC.framework/Version/Current/modules" ; \ + module="./VLC.framework/Version/Current/modules/`basename $$i`.dylib"; \ + install_name_tool -change /usr/local/lib/libvlc.1.dylib \ + @loader_path/../lib/libvlc.dylib \ + "$$module"; \ + echo "changing install name of $$module";\ + for lib in `otool -L "$$module" | grep @executable_path | sed 's/(\([0-z]*\ *\.*\,*\)*)//g'` ; do \ + install_name_tool -change "$$lib" \ + `echo "$$lib" | sed 's:executable_path:loader_path/../:'` \ + "$$module"; \ + done; \ + fi \ + done && \ + ln -sf Version/Current/modules VLC.framework + + +VLC.framework/share: + cp -R $(srcdir)/share ./VLC.framework/Version/Current && \ + ln -sf Version/Current/share ./VLC.framework + +VLC.framework/lib: + mkdir -p VLC.framework/Version/Current/lib && \ + if test -d $(srcdir)/extras/contrib/vlc-lib; then \ + for i in $(srcdir)/extras/contrib/vlc-lib/*.dylib ; do \ + module="VLC.framework/Version/Current/lib/`basename $${i}`"; \ + cp `pwd`/$${i} $${module} ; \ + install_name_tool -change /usr/local/lib/libvlc.1 @loader_path/../lib/libvlc.dylib \ + $${module}; \ + echo "changing install name of $$module";\ + for lib in `otool -L "$$module" | grep @executable_path | sed 's/(\([0-z]*\ *\.*\,*\)*)//g'` ; do \ + install_name_tool -change "$$lib" \ + `echo "$$lib" | sed 's:executable_path:loader_path/../:'` \ + "$$module"; \ + done; \ + done \ + fi && \ + ln -sf Version/Current/lib VLC.framework + +VLC.framework/VLC: + ln -sf Version/Current/VLC VLC.framework + +VLC.framework/Version/Current/VLC: $(OBJECTS) $(LIBVLC) VLC.framework/Headers VLC.framework/Resources VLC.framework/lib/libvlc-control.dylib VLC.framework/lib/libvlc.dylib VLC.framework/modules VLC.framework/share VLC.framework/VLC + mkdir -p VLC.framework/Version/Current/Framework && \ + $(CXX) -dynamiclib $(LDFLAGS) $(OBJECTS) $(FRAMEWORKS) $(LIBVLC) $(MODULES) $(LIBS) -install_name @loader_path/../Frameworks/VLC.framework/Version/Current/VLC -o VLC.framework/Version/Current/VLC && \ + install_name_tool -change /usr/local/lib/libvlc-control.0.dylib \ + `pwd`/VLC.framework/lib/libvlc-control.dylib \ + VLC.framework/Version/Current/VLC && \ + install_name_tool -change /usr/local/lib/libvlc.1.dylib \ + `pwd`/VLC.framework/lib/libvlc.dylib \ + VLC.framework/Version/Current/VLC && \ + touch VLC.framework + +VLC.framework:: VLC.framework/Version/Current/VLC + +.PHONY: clean + +clean: + rm -Rf VLC.framework + rm -Rf $(OBJECTS) *.o $(SRC_DIR)/*.o diff --git a/extras/MacOSX/Framework/Resources/Info.plist b/extras/MacOSX/Framework/Resources/Info.plist new file mode 100644 index 000000000000..fd4a8e4e1a86 --- /dev/null +++ b/extras/MacOSX/Framework/Resources/Info.plist @@ -0,0 +1,22 @@ +<?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>Quartz</string> + <key>CFBundleIdentifier</key> + <string>org.videolan.vlcframework</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>VLC</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>0.1</string> + <key>CFBundleVersion</key> + <string>0.1</string> +</dict> +</plist> diff --git a/extras/MacOSX/Framework/Resources/version.plist b/extras/MacOSX/Framework/Resources/version.plist new file mode 100644 index 000000000000..2d08db5e4249 --- /dev/null +++ b/extras/MacOSX/Framework/Resources/version.plist @@ -0,0 +1,12 @@ +<?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>CFBundleShortVersionString</key> + <string>0.1</string> + <key>CFBundleVersion</key> + <string>0.1</string> + <key>ProjectName</key> + <string>VLC</string> +</dict> +</plist> diff --git a/extras/MacOSX/Framework/Sources/VLCEventManager.m b/extras/MacOSX/Framework/Sources/VLCEventManager.m new file mode 100644 index 000000000000..8bc975c9e924 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCEventManager.m @@ -0,0 +1,218 @@ +/***************************************************************************** + * VLCTime.h: VLC.framework VLCTime implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 "VLCEventManager.h" +#import <pthread.h> + +static VLCEventManager * defaultManager = NULL; + +enum message_type_t +{ + VLCNotification, + VLCObjectMethodWithObjectArg +}; + +struct message { + id target; + SEL sel; + union u + { + NSString * name; + id object; + } u; + enum message_type_t type; +}; + +@interface VLCEventManager (Private) +- (void)callDelegateOfObjectAndSendNotificationWithArgs:(NSData*)data; +- (void)callObjectMethodWithArgs:(NSData*)data; +- (void)callDelegateOfObject:(id) aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName; +- (pthread_cond_t *)signalData; +- (pthread_mutex_t *)queueLock; +- (NSMutableArray *)messageQueue; +@end + +static void * EventDispatcherMainLoop(void * user_data) +{ + VLCEventManager * self = user_data; + + for(;;) + { + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + struct message * message, * message_newer = NULL; + NSData *dataMessage; + int i; + + /* Wait for some data */ + pthread_mutex_lock( [self queueLock] ); + + /* Wait until we have something on the queue */ + if ([[self messageQueue] count] <= 0 ) do { + pthread_cond_wait( [self signalData], [self queueLock] ); + } while([[self messageQueue] count] <= 0 ); + + message = (struct message *)[(NSData *)[[self messageQueue] lastObject] bytes]; + + /* Don't send the same notification twice */ + if( message->type == VLCNotification ) + { + for( i = 0; i < [[self messageQueue] count]-1; i++ ) + { + message_newer = (struct message *)[(NSData *)[[self messageQueue] objectAtIndex: i] bytes]; + if( message_newer->type != VLCNotification ) + continue; + if( message_newer->target == message->target && message_newer->target == message->target && [message_newer->u.name isEqualToString:message->u.name] ) + { + [message_newer->target release]; + [message->u.name release]; + [[self messageQueue] removeObjectAtIndex: i]; + i--; + } + } + } + + dataMessage = [[self messageQueue] lastObject]; + + pthread_mutex_unlock( [self queueLock] ); + + if( message->type == VLCNotification ) + [self performSelectorOnMainThread:@selector(callDelegateOfObjectAndSendNotificationWithArgs:) withObject:[dataMessage retain] waitUntilDone: NO]; + else + [self performSelectorOnMainThread:@selector(callObjectMethodWithArgs:) withObject:[dataMessage retain] waitUntilDone: NO]; + + pthread_mutex_lock( [self queueLock] ); + [[self messageQueue] removeLastObject]; + pthread_mutex_unlock( [self queueLock] ); + + [pool release]; + } +} + +@implementation VLCEventManager ++ (id)sharedManager +{ + /* We do want a lock here to avoid leaks */ + if ( !defaultManager ) + { + defaultManager = [[VLCEventManager alloc] init]; + } + + return defaultManager; +} + +- (id)init +{ + if( self = [super init] ) + { + pthread_mutex_init( &queueLock, NULL ); + pthread_cond_init( &signalData, NULL ); + pthread_create( &dispatcherThread, NULL, EventDispatcherMainLoop, self ); + messageQueue = [[NSMutableArray alloc] initWithCapacity:10]; + } + return self; +} + +- (void)dealloc +{ + pthread_kill( dispatcherThread, SIGKILL ); + pthread_join( dispatcherThread, NULL ); + [super dealloc]; +} + +- (void)callOnMainThreadDelegateOfObject:(id)aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + struct message message = { [aTarget retain], aSelector, [aNotificationName retain], VLCNotification }; + pthread_mutex_lock( [self queueLock] ); + [[self messageQueue] insertObject:[NSData dataWithBytes:&message length:sizeof(struct message)] atIndex:0]; + pthread_cond_signal( [self signalData] ); + pthread_mutex_unlock( [self queueLock] ); + [pool release]; +} + +- (void)callOnMainThreadObject:(id)aTarget withMethod:(SEL)aSelector withArgumentAsObject: (id)arg +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + struct message message = { [aTarget retain], aSelector, [arg retain], VLCObjectMethodWithObjectArg }; + pthread_mutex_lock( [self queueLock] ); + [[self messageQueue] insertObject:[NSData dataWithBytes:&message length:sizeof(struct message)] atIndex:0]; + pthread_cond_signal( [self signalData] ); + pthread_mutex_unlock( [self queueLock] ); + [pool release]; +} +@end + +@implementation VLCEventManager (Private) +- (void)callDelegateOfObjectAndSendNotificationWithArgs:(NSData*)data +{ + struct message * message = (struct message *)[data bytes]; + + [self callDelegateOfObject:message->target withDelegateMethod:message->sel withNotificationName:message->u.name]; + [message->u.name release]; + [message->target release]; + [data release]; +} + +- (void)callObjectMethodWithArgs:(NSData*)data +{ + struct message * message = (struct message *)[data bytes]; + void (*method)(id, SEL, id) = (void (*)(id, SEL, id))[message->target methodForSelector: message->sel]; + + method( message->target, message->sel, message->u.object); + [message->u.object release]; + [message->target release]; + [data release]; +} + + +- (NSMutableArray *)messageQueue +{ + return messageQueue; +} +- (pthread_cond_t *)signalData +{ + return &signalData; +} + +- (pthread_mutex_t *)queueLock +{ + return &queueLock; +} + +- (void)callDelegateOfObject:(id) aTarget withDelegateMethod:(SEL)aSelector withNotificationName: (NSString *)aNotificationName +{ + NSMethodSignature * aSignature; + NSInvocation * anInvocation; + + [[NSNotificationCenter defaultCenter] postNotification: [NSNotification notificationWithName:aNotificationName object:aTarget]]; + + if (![aTarget delegate] || ![[aTarget delegate] respondsToSelector: aSelector]) + return; + + /* NSInvocation could maybe be prefered here */ + void (*method)(id, SEL, id) = (void (*)(id, SEL, id))[[aTarget delegate] methodForSelector: aSelector]; + method( [aTarget delegate], aSelector, [NSNotification notificationWithName:aNotificationName object:aTarget]); + +} +@end diff --git a/extras/MacOSX/Framework/Sources/VLCLibrary.m b/extras/MacOSX/Framework/Sources/VLCLibrary.m new file mode 100644 index 000000000000..8fe754e8e8a8 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCLibrary.m @@ -0,0 +1,44 @@ +/***************************************************************************** + * VLCLibrary.h: VLC.framework VLCLibrary implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 "VLCLibrary.h" + +static libvlc_instance_t * shared_instance = NULL; + +@implementation VLCLibrary ++ (libvlc_instance_t *)sharedInstance +{ + if(!shared_instance) + { + libvlc_exception_t ex; + char *lib_vlc_params[] = { "vlc", "-I", "dummy", "-vvvvvv" }; + libvlc_exception_init( &ex ); + + shared_instance = libvlc_new( 4, lib_vlc_params, &ex ); + quit_on_exception( &ex ); + } + return shared_instance; +} +@end + diff --git a/extras/MacOSX/Framework/Sources/VLCMedia.m b/extras/MacOSX/Framework/Sources/VLCMedia.m new file mode 100644 index 000000000000..5ca7d998f133 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCMedia.m @@ -0,0 +1,257 @@ +/***************************************************************************** + * VLCMedia.m: VLC.framework VLCMedia implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCMedia.h> +#import <VLC/VLCPlaylist.h> +#import "VLCEventManager.h" +#import "VLCLibrary.h" + +#include <vlc/libvlc.h> + +NSString * VLCMetaInformationTitle = @"title"; +NSString * VLCMetaInformationAuthor = @"author"; +NSString * VLCMetaInformationArtwork = @"artwork"; + +/* Our notification */ +NSString * VLCMediaSubItemAdded = @"VLCMediaSubItemAdded"; +NSString * VLCMediaMetaChanged = @"VLCMediaMetaChanged"; + +/* libvlc event callback */ +static void HandleMediaSubItemAdded( const libvlc_event_t * event, void * self) +{ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(subItemAdded:) + withNotificationName: VLCMediaSubItemAdded]; +} + +/* libvlc event callback */ +static void HandleMediaMetaChanged( const libvlc_event_t * event, void * self) +{ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(metaChanged:) + withNotificationName: VLCMediaMetaChanged]; + +} + +@interface VLCMedia (Private) +- (void)initializeInternalMediaDescriptor; +- (void)subItemAdded:(NSNotification *)notification; +- (void)metaChanged:(NSNotification *)notification; +- (void)fetchMetaInformation; +@end + +@implementation VLCMedia (Private) +- (void)initializeInternalMediaDescriptor +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subItemAdded:) name:VLCMediaSubItemAdded object:self]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(metaChanged:) name:VLCMediaMetaChanged object:self]; + libvlc_exception_t ex; + libvlc_exception_init( &ex ); + libvlc_event_manager_t * p_em = libvlc_media_descriptor_event_manager( md, &ex ); + libvlc_event_attach( p_em, libvlc_MediaDescriptorSubItemAdded, HandleMediaSubItemAdded, self, &ex ); + libvlc_event_attach( p_em, libvlc_MediaDescriptorMetaChanged, HandleMediaMetaChanged, self, &ex ); + quit_on_exception( &ex ); + libvlc_media_list_t * p_mlist = libvlc_media_descriptor_subitems( md, NULL ); + if (!p_mlist) + subitems = nil; + else + { + subitems= [[VLCPlaylist playlistWithLibVLCMediaList: p_mlist] retain]; + libvlc_media_list_release( p_mlist ); + } + [self fetchMetaInformation]; +} + +- (void)subItemAdded:(NSNotification *)notification +{ + if(!subitems) + { + libvlc_media_list_t * p_mlist = libvlc_media_descriptor_subitems( md, NULL ); + [self willChangeValueForKey:@"subitems"]; + subitems = [[VLCPlaylist playlistWithLibVLCMediaList: p_mlist] retain]; + [self didChangeValueForKey:@"subitems"]; + libvlc_media_list_release( p_mlist ); + } +} +- (void)metaChanged:(NSNotification *)notification +{ + [self fetchMetaInformation]; +} + +- (void)fetchMetaInformation +{ + NSMutableDictionary * temp; + libvlc_exception_t ex; + char * title; + char * artist; + char * arturl = NULL; + + libvlc_exception_init( &ex ); + + title = libvlc_media_descriptor_get_meta( md, libvlc_meta_Title, &ex ); + quit_on_exception( &ex ); + + artist = libvlc_media_descriptor_get_meta( md, libvlc_meta_Artist, &ex ); + quit_on_exception( &ex ); + + arturl = libvlc_media_descriptor_get_meta( md, libvlc_meta_ArtworkURL, &ex ); + quit_on_exception( &ex ); + + temp = [NSMutableDictionary dictionaryWithCapacity: 2]; + + if (title) + [temp setObject: [NSString stringWithUTF8String: title] forKey: VLCMetaInformationTitle]; + +#if 0 + /* We need to perform that in a thread because this takes long. */ + if (arturl) + { + NSString *plainStringURL = [NSString stringWithUTF8String:arturl]; + NSString *escapedStringURL = [plainStringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSURL *aURL = [NSURL URLWithString:escapedStringURL]; + NSImage * art = [[NSImage alloc] initWithContentsOfURL: aURL]; + [art autorelease]; + if( art ) + [temp setObject: art forKey: VLCMetaInformationArtwork]; + } +#endif + + free( title ); + free( artist ); + free( arturl ); + + [self willChangeValueForKey:@"metaInformation"]; + if( metaInformation ) + [metaInformation release]; + metaInformation = [[NSMutableDictionary alloc] initWithDictionary:temp]; + [self didChangeValueForKey:@"metaInformation"]; +} +@end + +@implementation VLCMedia +- (id)initWithURL:(NSString *)anURL +{ + if (self = [super init]) + { + libvlc_exception_t ex; + url = [anURL copy]; + + libvlc_exception_init( &ex ); + + md = libvlc_media_descriptor_new( [VLCLibrary sharedInstance], + [anURL cString], + &ex ); + quit_on_exception( &ex ); + metaInformation = nil; + [self initializeInternalMediaDescriptor]; + } + return self; +} + ++ (id)mediaWithURL:(NSString *)anURL; +{ + return [[(VLCMedia*)[VLCMedia alloc] initWithURL: anURL ] autorelease]; +} + +- (void)release +{ + @synchronized(self) + { + if([self retainCount] <= 1) + { + /* We must make sure we won't receive new event after an upcoming dealloc + * We also may receive a -retain in some event callback that may occcur + * Before libvlc_event_detach. So this can't happen in dealloc */ + libvlc_event_manager_t * p_em = libvlc_media_descriptor_event_manager( md, NULL ); + libvlc_event_detach( p_em, libvlc_MediaDescriptorSubItemAdded, HandleMediaSubItemAdded, self, NULL ); + libvlc_event_detach( p_em, libvlc_MediaDescriptorMetaChanged, HandleMediaMetaChanged, self, NULL ); + } + [super release]; + } +} + +- (void) dealloc +{ + if( subitems ) + [subitems release]; + if( metaInformation ) + [metaInformation release]; + libvlc_media_descriptor_release( md ); + [url release]; + [super dealloc]; +} + +- (NSString *)url +{ + return [[url copy] autorelease]; +} + +- (VLCPlaylist *)subitems +{ + return subitems; +} + +/* Returns a dictionary with corresponding object associated with a meta */ +- (NSDictionary *)metaInformation +{ + return metaInformation; +} +/* Not supported yet */ +- (id)delegate +{ + return nil; +} +@end + +@implementation VLCMedia (LibVLCBridging) +- (id) initWithLibVLCMediaDescriptor: (libvlc_media_descriptor_t *)p_md +{ + if (self = [super init]) + { + libvlc_exception_t ex; + char * p_url; + libvlc_exception_init( &ex ); + + p_url = libvlc_media_descriptor_get_mrl( p_md, &ex ); + quit_on_exception( &ex ); + url = [[NSString stringWithCString: p_url] retain]; + libvlc_media_descriptor_retain( p_md ); + md = p_md; + [self initializeInternalMediaDescriptor]; + } + return self; +} + ++ (id) mediaWithLibVLCMediaDescriptor: (libvlc_media_descriptor_t *)p_md +{ + return [[[VLCMedia alloc] initWithLibVLCMediaDescriptor: p_md] autorelease]; +} + +- (libvlc_media_descriptor_t *) libVLCMediaDescriptor +{ + libvlc_media_descriptor_retain( md ); + return md; +} +@end \ No newline at end of file diff --git a/extras/MacOSX/Framework/Sources/VLCMediaDiscoverer.m b/extras/MacOSX/Framework/Sources/VLCMediaDiscoverer.m new file mode 100644 index 000000000000..5360ff3c0b72 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCMediaDiscoverer.m @@ -0,0 +1,110 @@ +/***************************************************************************** + * VLCMediaDiscoverer.m: VLC.framework VLCMediaDiscoverer implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCMediaDiscoverer.h> +#import "VLCLibrary.h" + +#include <vlc/libvlc.h> + + +@implementation VLCMediaDiscoverer +- (id)initWithName:(NSString *)aServiceName +{ + if (self = [super init]) + { + libvlc_exception_t ex; + libvlc_exception_init( &ex ); + localizedName = nil; + playlist = nil; + mdis = libvlc_media_discoverer_new_from_name( [VLCLibrary sharedInstance], + [aServiceName cString], + &ex ); + quit_on_exception( &ex ); + } + return self; +} + +- (void)dealloc +{ + if( localizedName ) + [localizedName release]; + if( playlist ) + [playlist release]; + libvlc_media_discoverer_release( mdis ); + [super dealloc]; +} + +- (VLCPlaylist *) playlist +{ + if( playlist ) + return playlist; + + libvlc_media_list_t * p_mlist = libvlc_media_discoverer_media_list( mdis ); + VLCPlaylist * ret = [VLCPlaylist playlistWithLibVLCMediaList: p_mlist]; + libvlc_media_list_release( p_mlist ); + + /* Hack until this gets done properly upstream */ + char * name = libvlc_media_discoverer_localized_name( mdis ); + if( !name ) + { + VLCMedia * media = [ret mediaAtIndex: 0]; + ret = media ? (VLCPlaylist *)[media subitems] : nil; + } + free(name); + + if( ret ) + { + playlist = [ret retain]; + } + return ret; +} + +- (NSString *)localizedName +{ + NSString * ret = nil; + char * name = libvlc_media_discoverer_localized_name( mdis ); + + if( localizedName ) + return localizedName; + + if (name) + { + ret = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; + free( name ); + } + /* XXX: Hack until this gets done properly upstream. This is really slow. */ + if (!ret) + { + libvlc_media_list_t * p_mlist = libvlc_media_discoverer_media_list( mdis ); + ret = [[[[VLCPlaylist playlistWithLibVLCMediaList: p_mlist] mediaAtIndex:0] metaInformation] objectForKey: VLCMetaInformationTitle]; + libvlc_media_list_release( p_mlist ); + } + if( ret ) + { + localizedName = [ret retain]; + } + return localizedName; +} +@end diff --git a/extras/MacOSX/Framework/Sources/VLCMediaLibrary.m b/extras/MacOSX/Framework/Sources/VLCMediaLibrary.m new file mode 100644 index 000000000000..0b028278dc62 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCMediaLibrary.m @@ -0,0 +1,87 @@ +/***************************************************************************** + * VLCMediaDiscoverer.m: VLC.framework VLCMediaDiscoverer implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCMediaLibrary.h> +#import "VLCLibrary.h" + +#include <vlc/libvlc.h> + +static VLCMediaLibrary * sharedMediaLibrary = NULL; + +@implementation VLCMediaLibrary ++ (id)sharedMediaLibrary +{ + if( !sharedMediaLibrary ) + { + sharedMediaLibrary = [[VLCMediaLibrary alloc] init]; + } + return sharedMediaLibrary; +} + +- (id)init +{ + if (self = [super init]) + { + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + mlib = libvlc_media_library_new( [VLCLibrary sharedInstance], &p_e ); + quit_on_exception( &p_e ); + libvlc_media_library_load( mlib, &p_e ); + quit_on_exception( &p_e ); + allMedia = nil; + } + return self; +} + +- (void)dealloc +{ + if (allMedia) + [allMedia release]; + libvlc_media_library_release( mlib ); + [super dealloc]; +} + +- (VLCPlaylist *)allMedia +{ + if (!allMedia) + { + libvlc_media_list_t * p_mlist = libvlc_media_library_media_list( mlib, NULL ); + libvlc_media_list_t * p_flat_mlist = libvlc_media_list_flat_media_list( p_mlist, NULL ); + allMedia = [[VLCPlaylist playlistWithLibVLCMediaList: p_flat_mlist] retain]; + libvlc_media_list_release( p_flat_mlist ); + libvlc_media_list_release( p_mlist ); + } + return allMedia; +} + +- (NSArray *) playlists +{ + libvlc_media_list_t * p_mlist = libvlc_media_library_media_list( mlib, NULL ); + VLCPlaylist * playlist = [VLCPlaylist playlistWithLibVLCMediaList: p_mlist]; + libvlc_media_list_release( p_mlist ); + NSArray * ret = [playlist sublists]; + return ret; +} +@end diff --git a/extras/MacOSX/Framework/Sources/VLCPlaylist.m b/extras/MacOSX/Framework/Sources/VLCPlaylist.m new file mode 100644 index 000000000000..d5d5e7fa9c95 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCPlaylist.m @@ -0,0 +1,355 @@ +/***************************************************************************** + * VLCPlaylist.h: VLC.framework VLCPlaylist implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <VLC/VLCPlaylist.h> +#import "VLCLibrary.h" +#import "VLCEventManager.h" +#import <vlc/vlc.h> +#import <vlc/libvlc.h> + +/* Our notification */ +NSString * VLCPlaylistItemChanged = @"VLCPlaylistItemChanged"; +NSString * VLCPlaylistItemDeleted = @"VLCPlaylistItemDeleted"; +NSString * VLCPlaylistItemAdded = @"VLCPlaylistItemAdded"; + +@interface VLCPlaylist (Private) +- (void)initializeInternalMediaList; + +- (void)removeObjectFromLibVLCInItemsAtIndex:(int) i; +- (void)insertObjectFromLibVLC:(id)object inItemsAtIndex:(int) i; +@end + +@interface VLCPlaylist (Binding) +/* Bindings */ +- (unsigned int)countOfItems; +- (id)objectInItemsAtIndex:(unsigned int)index; +- (void)insertObject:(id)anObject inItemsAtIndex:(unsigned int)index; +- (void)replaceObjectInItemsAtIndex:(unsigned int)index withObject:(id)anObject; +@end + +/* libvlc event callback */ +static void HandleMediaListItemDeleted( const libvlc_event_t * event, void * user_data) +{ + id self = user_data; + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#ifdef DONT_UPDATE_VARIABLES_FROM_NON_MAIN_THREAD_CAUSE_BINDINGS_DONT_LIKE + /* That would be nice to sync self's variables on non main thread, but + * I did experience some Bindings related crash with an NSTreeController */ + [self removeObjectFromLibVLCInItemsAtIndex: event->u.media_list_item_deleted.index]; +#endif + [[VLCEventManager sharedManager] callOnMainThreadObject:self withMethod:@selector(playlistItemRemoved:) withArgumentAsObject: + [NSNumber numberWithInt: event->u.media_list_item_deleted.index] ]; + +#ifdef DONT_SEND_NOTIFICATION_BECAUSE_WE_DONT_HAVE_TO + /* This was disabled to avoid non necessary overhead, but we may want to + * retablish that once the rest becomes more stable */ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(playlistItemAdded:) + withNotificationName: VLCPlaylistItemDeleted]; +#endif + [pool release]; +} + +/* libvlc event callback */ +static void HandleMediaListItemAdded( const libvlc_event_t * event, void * user_data) +{ + id self = user_data; + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#ifdef DONT_UPDATE_VARIABLES_FROM_NON_MAIN_THREAD_CAUSE_BINDINGS_DONT_LIKE + [self insertObjectFromLibVLC: [VLCMedia mediaWithLibVLCMediaDescriptor: event->u.media_list_item_added.item] + inItemsAtIndex: event->u.media_list_item_added.index ]; +#endif + [[VLCEventManager sharedManager] callOnMainThreadObject:self withMethod:@selector(playlistItemAdded:) withArgumentAsObject: + [NSArray arrayWithObjects: [VLCMedia mediaWithLibVLCMediaDescriptor: event->u.media_list_item_added.item], + [NSNumber numberWithInt: event->u.media_list_item_added.index], nil ] ]; + +#ifdef DONT_SEND_NOTIFICATION_BECAUSE_WE_DONT_HAVE_TO + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(playlistItemAdded:) + withNotificationName: VLCPlaylistItemAdded]; +#endif + [pool release]; +} + +@implementation VLCPlaylist (Private) +- (void)initializeInternalMediaList +{ + libvlc_exception_t p_e; + int i; + [self lock]; + items = [[NSMutableArray alloc] init]; + + for( i = 0; i < libvlc_media_list_count( p_mlist, NULL ); i++ ) + { + libvlc_media_descriptor_t * p_md; + p_md = libvlc_media_list_item_at_index( p_mlist, i, NULL ); + [items addObject:[VLCMedia mediaWithLibVLCMediaDescriptor: p_md]]; + libvlc_media_descriptor_release( p_md ); + } + + libvlc_event_manager_t * p_em = libvlc_media_list_event_manager( p_mlist, &p_e ); + libvlc_exception_init( &p_e ); + libvlc_event_attach( p_em, libvlc_MediaListItemDeleted, HandleMediaListItemDeleted, self, &p_e ); + libvlc_event_attach( p_em, libvlc_MediaListItemAdded, HandleMediaListItemAdded, self, &p_e ); + [self unlock]; + quit_on_exception( &p_e ); +} + +/* LibVLC callback, executed on main thread */ +- (void)playlistItemAdded:(NSArray *)args +{ + [self insertObjectFromLibVLC: [args objectAtIndex: 0] + inItemsAtIndex: [[args objectAtIndex: 1] intValue] ]; +} + +- (void)playlistItemRemoved:(NSNumber *)index +{ + [self removeObjectFromLibVLCInItemsAtIndex: [index intValue] ]; +} + +/* When LibVLC change its mlist's item this functions gets called */ +- (void)removeObjectFromLibVLCInItemsAtIndex:(int) i +{ + [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:[NSIndexSet indexSetWithIndex:i] forKey:@"items"]; + [items removeObjectAtIndex:i]; + [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:[NSIndexSet indexSetWithIndex:i] forKey:@"items"]; +} + +- (void)insertObjectFromLibVLC:(id)object inItemsAtIndex:(int) i +{ + [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:i] forKey:@"items"]; + [items insertObject:object atIndex: i]; + [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:i] forKey:@"items"]; +} + +@end + +@implementation VLCPlaylist (Binding) +/* "items" bindings */ +- (unsigned int)countOfItems +{ + return [items count]; +} + +- (id)objectInItemsAtIndex:(unsigned int)index +{ + return [items objectAtIndex:index]; +} + +/* Setters go through LibVLC */ +- (void)insertObject:(id)anObject inItemsAtIndex:(unsigned int)index +{ + [self insertMedia:anObject atIndex:index]; +} + +- (void)removeObjectFromItemsAtIndex:(unsigned int)index +{ + [self removeMediaAtIndex:index]; +} + +- (void)replaceObjectInItemsAtIndex:(unsigned int)index withObject:(id)anObject +{ + [self removeMediaAtIndex:index]; + [self insertMedia:anObject atIndex:index]; +} +@end + + +@implementation VLCPlaylist +- (id)init +{ + [VLCEventManager sharedManager]; + + if (self = [super init]) + { + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + p_mlist = libvlc_media_list_new( [VLCLibrary sharedInstance], &p_e ); + quit_on_exception( &p_e ); + [self initializeInternalMediaList]; + } + return self; +} + +- (void)release +{ + @synchronized(self) + { + if([self retainCount] <= 1) + { + /* We must make sure we won't receive new event after an upcoming dealloc + * We also may receive a -retain in some event callback that may occcur + * Before libvlc_event_detach. So this can't happen in dealloc */ + libvlc_event_manager_t * p_em = libvlc_media_list_event_manager( p_mlist, NULL ); + libvlc_event_detach( p_em, libvlc_MediaListItemDeleted, HandleMediaListItemDeleted, self, NULL ); + libvlc_event_detach( p_em, libvlc_MediaListItemAdded, HandleMediaListItemAdded, self, NULL ); + } + [super release]; + } +} + +- (void)dealloc +{ + libvlc_media_list_release( p_mlist ); + [items release]; + [super dealloc]; +} + +- (VLCMedia *)mediaAtIndex: (int)index +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_descriptor_t * p_md = libvlc_media_list_item_at_index( p_mlist, index, &p_e ); + quit_on_exception( &p_e ); + + return [VLCMedia mediaWithLibVLCMediaDescriptor: p_md]; +} + +- (int)countMedia +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + int count = libvlc_media_list_count( p_mlist, &p_e ); + quit_on_exception( &p_e ); + return count; +} + +- (NSArray *)sublists +{ + NSMutableArray * ret = [[NSMutableArray alloc] initWithCapacity: 0]; + int i, count; + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + count = libvlc_media_list_count( p_mlist, &p_e ); + quit_on_exception( &p_e ); + + for( i = 0; i < count; i++ ) + { + libvlc_media_descriptor_t * p_md; + libvlc_media_list_t * p_submlist; + p_md = libvlc_media_list_item_at_index( p_mlist, i, NULL ); + p_submlist = libvlc_media_descriptor_subitems( p_md, NULL ); + if( p_submlist ) + { + [ret addObject: [VLCPlaylist playlistWithLibVLCMediaList: p_submlist]]; + libvlc_media_list_release( p_submlist ); + } + libvlc_media_descriptor_release( p_md ); + } + return [ret autorelease]; +} + +- (VLCPlaylist *)flatPlaylist +{ + VLCPlaylist * flatPlaylist; + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_list_t * p_flat_mlist = libvlc_media_list_flat_media_list( p_mlist, &p_e ); + quit_on_exception( &p_e ); + flatPlaylist = [VLCPlaylist playlistWithLibVLCMediaList: p_flat_mlist]; + libvlc_media_list_release( p_flat_mlist ); + return flatPlaylist; +} + +- (VLCMedia *)providerMedia +{ + VLCMedia * ret; + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_descriptor_t * p_md = libvlc_media_list_media_descriptor( p_mlist, &p_e ); + ret = [VLCMedia mediaWithLibVLCMediaDescriptor: p_md]; + libvlc_media_descriptor_release( p_md ); + quit_on_exception( &p_e ); + return ret; +} + +- (void)addMedia: (VLCMedia *)item +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_descriptor_t * p_md = [item libVLCMediaDescriptor]; + libvlc_media_list_add_media_descriptor( p_mlist, p_md, &p_e ); + libvlc_media_descriptor_release( p_md ); + quit_on_exception( &p_e ); +} + +- (void)insertMedia: (VLCMedia *)item atIndex: (int)index +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_descriptor_t * p_md = [item libVLCMediaDescriptor]; + libvlc_media_list_insert_media_descriptor( p_mlist, p_md, index, &p_e ); + libvlc_media_descriptor_release( p_md ); + quit_on_exception( &p_e ); + +} + +- (void)removeMediaAtIndex: (int)index +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_list_remove_index( p_mlist, index, &p_e ); + quit_on_exception( &p_e ); +} + +- (void)lock +{ + libvlc_media_list_lock( p_mlist ); +} + +- (void)unlock +{ + libvlc_media_list_unlock( p_mlist ); +} + +- (id)delegate +{ + /* No delegate supported */ + return nil; +} +@end + +@implementation VLCPlaylist (LibVLCBridging) +- (id) initWithLibVLCMediaList: (libvlc_media_list_t *)p_new_mlist; +{ + if( self = [super init] ) + { + p_mlist = p_new_mlist; + libvlc_media_list_retain( p_mlist ); + [self initializeInternalMediaList]; + } + return self; +} + ++ (id) playlistWithLibVLCMediaList: (libvlc_media_list_t *)p_new_mlist; +{ + return [[[VLCPlaylist alloc] initWithLibVLCMediaList: p_new_mlist] autorelease]; +} + +- (libvlc_media_list_t *) libVLCMediaList +{ + libvlc_media_list_retain( p_mlist ); + return p_mlist; +} +@end \ No newline at end of file diff --git a/extras/MacOSX/Framework/Sources/VLCPlaylistDataSource.m b/extras/MacOSX/Framework/Sources/VLCPlaylistDataSource.m new file mode 100644 index 000000000000..0a0f75541c25 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCPlaylistDataSource.m @@ -0,0 +1,178 @@ +/***************************************************************************** + * VLCPlaylistDataSource.m: VLC.framework VLCPlaylistDataSource implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <VLC/VLCPlaylistDataSource.h> +#import "VLCEventManager.h" + +@implementation VLCPlaylistDataSource + +- (id)init +{ + if (self = [super init]) + { + playlist = nil; + videoView = nil; + } + return self; +} + +- (id)initWithPlaylist:(VLCPlaylist *)aPlaylist +{ + if (self = [super init]) + { + + playlist = [aPlaylist retain]; + + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(playlistDidChange:) name:VLCPlaylistItemAdded object:nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(itemDidAddSubitem:) name:VLCMediaSubItemAdded object:nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(itemDidChange:) name:VLCPlaylistItemChanged object:nil]; + videoView = nil; + outlineView = nil; + + } + return self; +} + +- (id)initWithPlaylist:(VLCPlaylist *)aPlaylist videoView:(VLCVideoView *)aVideoView; +{ + if (self = [super init]) + { + playlist = [aPlaylist retain]; + + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(playlistDidChange:) name:VLCPlaylistItemAdded object:nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(itemDidAddSubitem:) name:VLCMediaSubItemAdded object:nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(itemDidChange:) name:VLCPlaylistItemChanged object:nil]; + + videoView = [aVideoView retain]; + /* Will be automatically set if an outline view ask us data, + * be careful not to connect two outlineView to this object or this goes wrong. */ + outlineView = nil; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver: self]; + + if (playlist) + [playlist release]; + if (videoView) + [videoView release]; + + [super dealloc]; +} + +- (VLCPlaylist *)playlist +{ + return playlist; +} + +- (VLCVideoView *)videoView +{ + return videoView; +} +@end + + + +@implementation VLCPlaylistDataSource (OutlineViewDataSource) +- (BOOL) outlineView: (NSOutlineView *)ov isItemExpandable: (id)item { return NO; } +- (int) outlineView: (NSOutlineView *)ov numberOfChildrenOfItem:(id)item { return 0; } +- (id) outlineView: (NSOutlineView *)ov child:(int)index ofItem:(id)item { return nil; } +- (id) outlineView: (NSOutlineView *)ov objectValueForTableColumn:(NSTableColumn*)col byItem:(id)item { return nil; } +@end + +@implementation VLCPlaylistDataSource (TableViewDropping) +/* Dummy implementation cause we need them */ +- (int)numberOfRowsInTableView:(NSTableView *)aTableView { return 0; } +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex {return nil;} + +- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op +{ + return NSDragOperationEvery; /* This is for now */ +} + +- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info + row:(int)row dropOperation:(NSTableViewDropOperation)operation +{ + int i; + NSArray * droppedItems = [[info draggingPasteboard] propertyListForType: NSFilenamesPboardType]; + + for (i = 0; i < [droppedItems count]; i++) + { + NSString * filename = [droppedItems objectAtIndex:i]; + + [[self playlist] insertMedia:[VLCMedia mediaWithURL:filename] atIndex:row+i]; + } + +} +@end + +@interface NSObject (UnknownBindingsObject) +/* OutlineViewDataSourceDropping and bindings hack */ +- (id)observedObject; +@end + +@implementation VLCPlaylistDataSource (OutlineViewDataSourceDropping) +- (BOOL)outlineView:(NSOutlineView *)aOutlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index +{ + NSArray * droppedItems = [[info draggingPasteboard] propertyListForType: NSFilenamesPboardType]; + VLCPlaylist * aPlaylist; + int i; + + if (!item) + item = [self playlist]; /* The root object is our playlist */ + else + item = [item observedObject]; + + if (![item isMemberOfClass:[VLCPlaylist class]]) + return NO; + + if (index < 0) /* No precise item given, put it as the first one */ + index = 0; + + aPlaylist = item; + + if (!droppedItems) + { + /* XXX: localization */ + NSRunCriticalAlertPanelRelativeToWindow(@"Error", @"Unable to drop the provided item.", @"OK", nil, nil, [outlineView window]); + return NO; + } + + for (i = 0; i < [droppedItems count]; i++) + { + NSString * filename = [droppedItems objectAtIndex:i]; + + [aPlaylist insertMedia:[VLCMedia mediaWithURL:filename] atIndex:index+i]; + } + return YES; +} + +- (NSDragOperation)outlineView:(NSOutlineView *)aOutlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index +{ + return NSDragOperationEvery; +} +@end \ No newline at end of file diff --git a/extras/MacOSX/Framework/Sources/VLCServicesDiscoverer.m b/extras/MacOSX/Framework/Sources/VLCServicesDiscoverer.m new file mode 100644 index 000000000000..bc000f0d1e73 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCServicesDiscoverer.m @@ -0,0 +1,60 @@ +/***************************************************************************** + * VLCMediaDiscoverer.m: VLC.framework VLCMediaDiscoverer implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <Cocoa/Cocoa.h> +#import <VLC/VLCServicesDiscoverer.h> +#import <VLC/VLCMediaDiscoverer.h> +#import "VLCLibrary.h" + +#include <vlc/libvlc.h> + +static VLCServicesDiscoverer * sharedDiscoverer = NULL; + +@implementation VLCServicesDiscoverer ++ (id)sharedDiscoverer +{ + if (!sharedDiscoverer) + { + sharedDiscoverer = [[self alloc] init]; + } + return sharedDiscoverer; +} + +- (id) init +{ + if( self = [super init] ) + { + services = [[NSArray arrayWithObjects: + [[[VLCMediaDiscoverer alloc] initWithName:@"sap"] autorelease], + [[[VLCMediaDiscoverer alloc] initWithName:@"shoutcast"] autorelease], + [[[VLCMediaDiscoverer alloc] initWithName:@"shoutcasttv"] autorelease], nil] retain]; + } + return self; +} + +- (NSArray *) services +{ + return [[services copy] autorelease]; +} +@end diff --git a/extras/MacOSX/Framework/Sources/VLCTime.m b/extras/MacOSX/Framework/Sources/VLCTime.m new file mode 100644 index 000000000000..f240c9582e80 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCTime.m @@ -0,0 +1,56 @@ +/***************************************************************************** + * VLCTime.h: VLC.framework VLCTime implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <VLC/VLCTime.h> + +@implementation VLCTime +- (id)initWithNumber:(NSNumber *)aNumber +{ + if (self = [super init]) + { + value = [aNumber copy]; + } + return self; +} + +- (void)dealloc +{ + [value release]; + [super dealloc]; +} + +- (NSNumber *)numberRepresentation +{ + [[value copy] autorelease]; +} + +- (NSString *)stringRepresentation +{ + int hours = [value intValue] / (3600*1000); + int minutes = ([value intValue] - hours * 3600) / (60*1000); + int seconds = ([value intValue] - hours * 3600 * 1000 - minutes * 60 * 1000)/1000; + + return [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds]; +} +@end diff --git a/extras/MacOSX/Framework/Sources/VLCVideoView.m b/extras/MacOSX/Framework/Sources/VLCVideoView.m new file mode 100644 index 000000000000..b721844e25bd --- /dev/null +++ b/extras/MacOSX/Framework/Sources/VLCVideoView.m @@ -0,0 +1,272 @@ +/***************************************************************************** + * VLCVideoView.h: VLC.framework VLCVideoView implementation + ***************************************************************************** + * Copyright (C) 2007 Pierre d'Herbemont + * Copyright (C) 2007 the VideoLAN team + * $Id$ + * + * Authors: Pierre d'Herbemont <pdherbemont # videolan.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 <VLC/VLCVideoView.h> +#import "VLCLibrary.h" +#import "VLCEventManager.h" + +/* Libvlc */ +#include <vlc/vlc.h> +#include <vlc/libvlc.h> + +/* Notification */ +NSString * VLCVideoDidChangeVolume = @"VLCVideoDidChangeVolume"; +NSString * VLCVideoDidChangeTime = @"VLCVideoDidChangeTime"; +NSString * VLCVideoDidChangeCurrentlyPlayingItem = @"VLCVideoDidChangeCurrentlyPlayingItem"; +NSString * VLCVideoDidPause = @"VLCVideoDidPause"; +NSString * VLCVideoDidPlay = @"VLCVideoDidPlay"; +NSString * VLCVideoDidStop = @"VLCVideoDidStop"; + +static void HandleMediaListPlayerCurrentPlayingItemChanged( const libvlc_event_t * event, void * self ) +{ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(volumeDidChangeCurrentPlayingItem:) + withNotificationName: VLCVideoDidChangeCurrentlyPlayingItem]; +} + +static void HandleMediaListPlayerPaused( const libvlc_event_t * event, void * self ) +{ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(videoDidPause:) + withNotificationName: VLCVideoDidPause]; +} + +static void HandleMediaListPlayerPlayed( const libvlc_event_t * event, void * self ) +{ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(videoDidPlay:) + withNotificationName: VLCVideoDidPlay]; +} + +static void HandleMediaListPlayerStopped( const libvlc_event_t * event, void * self ) +{ + [[VLCEventManager sharedManager] callOnMainThreadDelegateOfObject: self + withDelegateMethod: @selector(videoDidStop:) + withNotificationName: VLCVideoDidStop]; +} + +@implementation VLCVideoView +- (id)initWithFrame:(NSRect)frameRect +{ + if (self = [super initWithFrame: frameRect]) + { + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + p_mi = libvlc_media_instance_new( [VLCLibrary sharedInstance], &p_e ); + quit_on_exception( &p_e ); + p_mlp = libvlc_media_list_player_new( [VLCLibrary sharedInstance], &p_e ); + quit_on_exception( &p_e ); + libvlc_media_list_player_set_media_instance( p_mlp, p_mi, &p_e ); + quit_on_exception( &p_e ); + libvlc_media_instance_set_drawable( p_mi, (libvlc_drawable_t)self, &p_e ); + quit_on_exception( &p_e ); + + libvlc_event_manager_t * p_em = libvlc_media_list_event_manager( p_mlp, &p_e ); + //libvlc_event_attach( p_em, libvlc_MediaListPlayerCurrentPlayingItemChanged, HandleMediaListPlayerCurrentPlayingItemChanged, self, &p_e ); + //libvlc_event_attach( p_em, libvlc_MediaListPlayerPaused, HandleMediaListPlayerPaused, self, &p_e ); + //libvlc_event_attach( p_em, libvlc_MediaListPlayerPlayed, HandleMediaListPlayerPlayed, self, &p_e ); + //libvlc_event_attach( p_em, libvlc_MediaListPlayerStopped, HandleMediaListPlayerStopped, self, &p_e ); + quit_on_exception( &p_e ); + + delegate = nil; + playlist = nil; + + [self setStretchesVideo: NO]; + [self setAutoresizesSubviews: YES]; + } + return self; +} + +- (void)dealloc +{ + libvlc_media_instance_release( p_mi ); + + if (delegate) + { + [delegate release]; + delegate = nil; + } + [super dealloc]; +} + +- (void)setPlaylist: (VLCPlaylist *)newPlaylist +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + + if (playlist) + [playlist release]; + + playlist = [newPlaylist retain]; + + libvlc_media_list_player_set_media_list( p_mlp, [playlist libVLCMediaList], &p_e ); + quit_on_exception( &p_e ); +} + +- (VLCPlaylist *)playlist +{ + return playlist; +} + +/* Play */ +- (void)play +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_list_player_play( p_mlp, &p_e ); + quit_on_exception( &p_e ); +} + +- (void)playItemAtIndex:(int) i +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_list_player_play_item_at_index( p_mlp, i, &p_e ); + quit_on_exception( &p_e ); +} + +- (void)playMedia:(VLCMedia *) media +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + libvlc_media_list_player_play_item( p_mlp, [media libVLCMediaDescriptor], &p_e ); + quit_on_exception( &p_e ); +} + +- (void)pause +{ + libvlc_exception_t p_e; + libvlc_exception_init( &p_e ); + //libvlc_media_list_player_pause( p_mlp, &p_e ); + quit_on_exception( &p_e ); +} + +- (void)setCurrentTime:(VLCTime *)timeObj +{ + +} + +/* State */ +- (BOOL)isPlaying +{ + //libvlc_media_list_player_is_playing( p_mlp, &p_e ); + //quit_on_exception( &p_e ); + return FALSE; +} + +- (BOOL)isPaused +{ + return FALSE; +} + +- (VLCTime *)currentTime +{ + return NULL; +} + +- (id)currentPlaylistItem +{ + return NULL; +} + +/* Video output property */ +- (void)setStretchesVideo:(BOOL)flag +{ + stretchVideo = flag; +} + +- (BOOL)stretchesVideo +{ + return stretchVideo; +} + +/* Fullscreen */ +- (void)enterFullscreen +{ + +} + +- (void)leaveFullscreen +{ + +} + +/* Delegate */ +- (void)setDelegate: (id)newDelegate +{ + if (delegate) + [delegate release]; + delegate = [newDelegate retain]; +} + +- (id)delegate +{ + return delegate; +} +@end + +@implementation VLCVideoView (NSViewSubclass) +- (void)drawRect:(NSRect)aRect +{ + [self lockFocus]; + [[NSColor blackColor] set]; + NSRectFill(aRect); + [self unlockFocus]; +} +- (BOOL)preservesContentDuringLiveResize +{ + return NO;//YES; +} +- (BOOL)isOpaque +{ + return YES; +} +@end + +@interface VLCOpenGLVoutView : NSView + /* This is part of the hack to avoid a warning in -[VLCVideoView addVoutSubview:] */ +- (void)detachFromVout; +@end + +@implementation VLCVideoView (VLCOpenGLVoutEmbedding) +/* This is called by the libvlc module 'macosx' as soon as there is one vout + * available */ +- (void)addVoutSubview:(id)aView +{ + if( [[self subviews] count] ) + { + /* XXX: This is a hack until core gets fixed */ + int i; + for( i = 0; i < [[self subviews] count]; i++ ) + { + [[[self subviews] objectAtIndex: i] detachFromVout]; + [[[self subviews] objectAtIndex: i] retain]; + [[[self subviews] objectAtIndex: i] removeFromSuperview]; + } + } + [self addSubview: aView]; + [aView setFrame: [self bounds]]; + [aView setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; +} +@end diff --git a/extras/MacOSX/Framework/Sources/test.m b/extras/MacOSX/Framework/Sources/test.m new file mode 100644 index 000000000000..d9d49005cdf9 --- /dev/null +++ b/extras/MacOSX/Framework/Sources/test.m @@ -0,0 +1,13 @@ +// +// test.m - Nothing useful yet +// VLC.framework +// +// Created by Pierre d'Herbemont on 13/04/07. +// Copyright __MyCompanyName__ 2007. All rights reserved. +// +#include <VLC/VLC.h> + +int test_vlc_framework() +{ + return 0xbabe; +} -- GitLab