diff options
-rw-r--r-- | macosx/DriveDetector.h | 23 | ||||
-rw-r--r-- | macosx/DriveDetector.m | 142 | ||||
-rw-r--r-- | macosx/HandBrake.xcodeproj/project.pbxproj | 6 |
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; }; |