summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macosx/DriveDetector.h23
-rw-r--r--macosx/DriveDetector.m142
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj6
3 files changed, 171 insertions, 0 deletions
diff --git a/macosx/DriveDetector.h b/macosx/DriveDetector.h
new file mode 100644
index 000000000..2018309b1
--- /dev/null
+++ b/macosx/DriveDetector.h
@@ -0,0 +1,23 @@
+/* DriveDetector.h $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.m0k.org/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Cocoa/Cocoa.h>
+
+@interface DriveDetector : NSObject
+{
+ id fTarget;
+ SEL fSelector;
+
+ int fCount;
+ NSMutableDictionary * fDrives;
+ NSTimer * fTimer;
+}
+
+- (id) initWithCallback: (id) target selector: (SEL) selector;
+- (void) run;
+- (void) stop;
+
+@end
diff --git a/macosx/DriveDetector.m b/macosx/DriveDetector.m
new file mode 100644
index 000000000..61f722960
--- /dev/null
+++ b/macosx/DriveDetector.m
@@ -0,0 +1,142 @@
+/* DriveDetector.m $
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.m0k.org/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include <paths.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IODVDMedia.h>
+
+#include "DriveDetector.h"
+#include "hb.h"
+
+@interface DriveDetector (Private)
+
+- (void) detectTimer: (NSTimer *) timer;
+
+@end
+
+@implementation DriveDetector
+
+- (void) dealloc
+{
+ [fDrives release];
+ [super dealloc];
+}
+
+- (id) initWithCallback: (id) target selector: (SEL) selector
+{
+ fTarget = target;
+ fSelector = selector;
+
+ fCount = -1;
+ fDrives = [[NSMutableDictionary alloc] initWithCapacity: 1];
+
+ return self;
+}
+
+- (void) run
+{
+ /* Set up a timer to check devices every second */
+ fTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self
+ selector: @selector( detectTimer: ) userInfo: nil repeats: YES];
+ [[NSRunLoop currentRunLoop] addTimer: fTimer forMode:
+ NSModalPanelRunLoopMode];
+
+ /* Do a first update right away */
+ [fTimer fire];
+}
+
+- (void) stop
+{
+ [fTimer invalidate];
+}
+
+- (void) detectTimer: (NSTimer *) timer
+{
+ /* Scan DVD drives (stolen from VLC) */
+ io_object_t next_media;
+ mach_port_t master_port;
+ kern_return_t kern_result;
+ io_iterator_t media_iterator;
+ CFMutableDictionaryRef classes_to_match;
+
+ kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
+ if( kern_result != KERN_SUCCESS )
+ {
+ return;
+ }
+
+ classes_to_match = IOServiceMatching( kIODVDMediaClass );
+ if( classes_to_match == NULL )
+ {
+ return;
+ }
+
+ CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectableKey ),
+ kCFBooleanTrue );
+
+ kern_result = IOServiceGetMatchingServices( master_port,
+ classes_to_match, &media_iterator );
+ if( kern_result != KERN_SUCCESS )
+ {
+ return;
+ }
+
+ [fDrives removeAllObjects];
+
+ next_media = IOIteratorNext( media_iterator );
+ if( next_media )
+ {
+ char * name;
+ char psz_buf[0x32];
+ size_t dev_path_length;
+ CFTypeRef str_bsd_path;
+ do
+ {
+ str_bsd_path =
+ IORegistryEntryCreateCFProperty( next_media,
+ CFSTR( kIOBSDNameKey ),
+ kCFAllocatorDefault,
+ 0 );
+ if( str_bsd_path == NULL )
+ {
+ IOObjectRelease( next_media );
+ continue;
+ }
+
+ snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
+ dev_path_length = strlen( psz_buf );
+
+ if( CFStringGetCString( (CFStringRef) str_bsd_path,
+ (char*)&psz_buf + dev_path_length,
+ sizeof(psz_buf) - dev_path_length,
+ kCFStringEncodingASCII ) )
+ {
+ if( ( name = hb_dvd_name( psz_buf ) ) )
+ {
+ [fDrives setObject: [NSString stringWithCString: psz_buf]
+ forKey: [NSString stringWithCString: name]];
+ }
+ }
+
+ CFRelease( str_bsd_path );
+
+ IOObjectRelease( next_media );
+
+ } while( ( next_media = IOIteratorNext( media_iterator ) ) );
+ }
+
+ IOObjectRelease( media_iterator );
+
+ if( [fDrives count] != fCount )
+ {
+ [fTarget performSelector: fSelector withObject: fDrives];
+ fCount = [fDrives count];
+ }
+}
+
+@end
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
index ba993f884..81f12911a 100644
--- a/macosx/HandBrake.xcodeproj/project.pbxproj
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -109,6 +109,7 @@
593034EC0BBA39A100172349 /* ChapterTitles.m in Sources */ = {isa = PBXBuildFile; fileRef = 593034EA0BBA39A100172349 /* ChapterTitles.m */; };
59CBD2370BBB44DA004A3BE3 /* parsecsv.c in Sources */ = {isa = PBXBuildFile; fileRef = 59CBD2360BBB44DA004A3BE3 /* parsecsv.c */; };
59CBD2650BBB4D1B004A3BE3 /* ChapterTitles.m in Sources */ = {isa = PBXBuildFile; fileRef = 593034EA0BBA39A100172349 /* ChapterTitles.m */; };
+ A2122D820C7EAF6600AB87A4 /* DriveDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = A2122D810C7EAF6600AB87A4 /* DriveDetector.m */; };
A273E04E0C57B39A00493A45 /* Add.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A273E0470C57B39A00493A45 /* Add.tiff */; };
A273E04F0C57B39A00493A45 /* Brushed Window.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A273E0480C57B39A00493A45 /* Brushed Window.tiff */; };
A273E0500C57B39A00493A45 /* Drawer-List2.png in Resources */ = {isa = PBXBuildFile; fileRef = A273E0490C57B39A00493A45 /* Drawer-List2.png */; };
@@ -251,6 +252,8 @@
593034E90BBA39A100172349 /* ChapterTitles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChapterTitles.h; sourceTree = "<group>"; };
593034EA0BBA39A100172349 /* ChapterTitles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChapterTitles.m; sourceTree = "<group>"; };
59CBD2360BBB44DA004A3BE3 /* parsecsv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = parsecsv.c; path = ../test/parsecsv.c; sourceTree = SOURCE_ROOT; };
+ A2122D800C7EAF6500AB87A4 /* DriveDetector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DriveDetector.h; sourceTree = "<group>"; };
+ A2122D810C7EAF6600AB87A4 /* DriveDetector.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DriveDetector.m; sourceTree = "<group>"; };
A273E0470C57B39A00493A45 /* Add.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Add.tiff; sourceTree = "<group>"; };
A273E0480C57B39A00493A45 /* Brushed Window.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "Brushed Window.tiff"; sourceTree = "<group>"; };
A273E0490C57B39A00493A45 /* Drawer-List2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Drawer-List2.png"; sourceTree = "<group>"; };
@@ -472,6 +475,8 @@
526FBC940B4CAA310064E04C /* Instant HandBrake Sources */ = {
isa = PBXGroup;
children = (
+ A2122D800C7EAF6500AB87A4 /* DriveDetector.h */,
+ A2122D810C7EAF6600AB87A4 /* DriveDetector.m */,
4D1EA31A0993B24700FDC1A2 /* ExpressController.h */,
4D1EA31B0993B24700FDC1A2 /* ExpressController.m */,
4D1EA2DC0993B01000FDC1A2 /* Express.plist */,
@@ -782,6 +787,7 @@
4D1EA2EA0993B09A00FDC1A2 /* main.mm in Sources */,
4D1EA31C0993B24700FDC1A2 /* ExpressController.m in Sources */,
4D3ECC2709A4917000B2E45F /* WhiteBox.m in Sources */,
+ A2122D820C7EAF6600AB87A4 /* DriveDetector.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};