summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
authorDamiano Galassi <[email protected]>2019-08-11 09:07:20 +0200
committerDamiano Galassi <[email protected]>2019-08-11 09:07:20 +0200
commitbed55e05880f0286f504142a48089bce60c96cc7 (patch)
tree795647e216e70981acc9ba0769eb03c53da44023 /macosx
parent6437b9d6653352011dc8af541b373369c45c8d44 (diff)
MacGui: move the queue libhb instance to an xpc service.
Diffstat (limited to 'macosx')
-rw-r--r--macosx/HBAudio.m2
-rw-r--r--macosx/HBCodingUtilities.h4
-rw-r--r--macosx/HBController.m36
-rw-r--r--macosx/HBOutputFileWriter.h2
-rw-r--r--macosx/HBOutputFileWriter.m7
-rw-r--r--macosx/HBOutputPanelController.h11
-rw-r--r--macosx/HBOutputPanelController.m153
-rw-r--r--macosx/HBOutputRedirect.h16
-rw-r--r--macosx/HBOutputRedirect.m131
-rw-r--r--macosx/HBQueue.h6
-rw-r--r--macosx/HBQueue.m51
-rw-r--r--macosx/HBQueueController.m58
-rw-r--r--macosx/HBRedirect.h37
-rw-r--r--macosx/HBRedirect.m146
-rw-r--r--macosx/HBRemoteCore.h40
-rw-r--r--macosx/HBRemoteCore.m167
-rw-r--r--macosx/HBStateFormatter.m5
-rw-r--r--macosx/HBSubtitles.m2
-rw-r--r--macosx/HBSubtitlesDefaults.m2
-rw-r--r--macosx/HBUtilities.h1
-rw-r--r--macosx/HBUtilities.m5
-rw-r--r--macosx/HandBrake.xcodeproj/project.pbxproj370
-rw-r--r--macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake-Release-Sandbox.xcscheme1
-rw-r--r--macosx/HandBrakeKit/HandBrakeKit.h1
-rw-r--r--macosx/HandBrakeXPCService/HBRemoteCoreProtocol.h41
-rw-r--r--macosx/HandBrakeXPCService/HandBrakeXPCService.entitlements20
-rw-r--r--macosx/HandBrakeXPCService/HandBrakeXPCService.h13
-rw-r--r--macosx/HandBrakeXPCService/HandBrakeXPCService.m193
-rw-r--r--macosx/HandBrakeXPCService/Info.plist29
-rw-r--r--macosx/HandBrakeXPCService/main.m38
30 files changed, 1298 insertions, 290 deletions
diff --git a/macosx/HBAudio.m b/macosx/HBAudio.m
index 231b7bc2e..cdd929efb 100644
--- a/macosx/HBAudio.m
+++ b/macosx/HBAudio.m
@@ -278,7 +278,7 @@ NSString *HBAudioEncoderChangedNotification = @"HBAudioEncoderChangedNotificatio
self = [super init];
decodeInt(_container); if (_container != HB_MUX_MP4 && _container != HB_MUX_MKV && _container != HB_MUX_WEBM) { goto fail; }
- decodeCollectionOfObjects(_sourceTracks, NSArray, NSDictionary);
+ decodeCollectionOfObjects3(_sourceTracks, NSArray, NSDictionary, NSString, NSNumber);
decodeCollectionOfObjects(_tracks, NSMutableArray, HBAudioTrack);
for (HBAudioTrack *track in _tracks)
diff --git a/macosx/HBCodingUtilities.h b/macosx/HBCodingUtilities.h
index 8635720ea..e0f3e1f04 100644
--- a/macosx/HBCodingUtilities.h
+++ b/macosx/HBCodingUtilities.h
@@ -25,5 +25,9 @@
#define decodeCollectionOfObjects3(x, cl, objectcl, objectcl2, objectcl3) x = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[cl class], [objectcl class], [objectcl2 class], [objectcl3 class], nil] forKey:OBJC_STRINGIFY(x)];
+#define decodeCollectionOfObjects4(x, cl, objectcl, objectcl2, objectcl3, objectcl4) x = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[cl class], [objectcl class], [objectcl2 class], [objectcl3 class], [objectcl4 class], nil] forKey:OBJC_STRINGIFY(x)];
+
+#define decodeCollectionOfObjects5(x, cl, objectcl, objectcl2, objectcl3, objectcl4, objectcl5) x = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[cl class], [objectcl class], [objectcl2 class], [objectcl3 class], [objectcl4 class], [objectcl5 class], nil] forKey:OBJC_STRINGIFY(x)];
+
#define decodeObjectOrFail(x, cl) x = [decoder decodeObjectOfClass:[cl class] forKey:OBJC_STRINGIFY(x)]; if (x == nil) {NSLog(@"Failed to decode: %@", OBJC_STRINGIFY(x)); goto fail;}
diff --git a/macosx/HBController.m b/macosx/HBController.m
index c2a4716f0..8f45ca51f 100644
--- a/macosx/HBController.m
+++ b/macosx/HBController.m
@@ -41,7 +41,6 @@
#import "HBPreferencesKeys.h"
static void *HBControllerScanCoreContext = &HBControllerScanCoreContext;
-static void *HBControllerQueueCoreContext = &HBControllerQueueCoreContext;
@interface HBController () <HBPresetsViewControllerDelegate, HBTitleSelectionDelegate, NSDraggingDestination, NSPopoverDelegate>
{
@@ -279,13 +278,9 @@ static void *HBControllerQueueCoreContext = &HBControllerQueueCoreContext;
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
context:HBControllerScanCoreContext];
- [self.queue.core addObserver:self forKeyPath:@"state"
- options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
- context:HBControllerQueueCoreContext];
-
- [self.queue addObserver:self forKeyPath:@"pendingItemsCount"
- options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
- context:HBControllerQueueCoreContext];
+ [NSNotificationCenter.defaultCenter addObserverForName:HBQueueDidChangeStateNotification object:_queue queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull note) {
+ [self updateQueueUI];
+ }];
[NSNotificationCenter.defaultCenter addObserverForName:HBQueueDidStartNotification object:_queue queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull note) {
self.bottomConstrain.animator.constant = 0;
@@ -383,24 +378,25 @@ static void *HBControllerQueueCoreContext = &HBControllerQueueCoreContext;
[self _touchBar_validateUserInterfaceItems];
}
}
- else if (context == HBControllerQueueCoreContext)
- {
- [self updateToolbarButtonsState];
- [self.window.toolbar validateVisibleItems];
- if (@available(macOS 10.12.2, *))
- {
- [self _touchBar_updateQueueButtonsState];
- [self _touchBar_validateUserInterfaceItems];
- }
- NSUInteger count = self.queue.pendingItemsCount;
- self.showQueueToolbarItem.badgeValue = count ? @(count).stringValue : nil;
- }
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
+- (void)updateQueueUI
+{
+ [self updateToolbarButtonsState];
+ [self.window.toolbar validateVisibleItems];
+ if (@available(macOS 10.12.2, *))
+ {
+ [self _touchBar_updateQueueButtonsState];
+ [self _touchBar_validateUserInterfaceItems];
+ }
+ NSUInteger count = self.queue.pendingItemsCount;
+ self.showQueueToolbarItem.badgeValue = count ? @(count).stringValue : nil;
+}
+
- (void)updateToolbarButtonsStateForScanCore:(HBState)state
{
if (state == HBStateIdle)
diff --git a/macosx/HBOutputFileWriter.h b/macosx/HBOutputFileWriter.h
index a6e22680c..480f198ca 100644
--- a/macosx/HBOutputFileWriter.h
+++ b/macosx/HBOutputFileWriter.h
@@ -5,7 +5,7 @@
It may be used under the terms of the GNU General Public License. */
#import <Foundation/Foundation.h>
-#import "HBOutputRedirect.h"
+#import "HBRedirect.h"
NS_ASSUME_NONNULL_BEGIN
diff --git a/macosx/HBOutputFileWriter.m b/macosx/HBOutputFileWriter.m
index 8534308c9..bbc802492 100644
--- a/macosx/HBOutputFileWriter.m
+++ b/macosx/HBOutputFileWriter.m
@@ -74,12 +74,7 @@
fflush(f);
}
-- (void)stdoutRedirect:(NSString *)text
-{
- [self write:text];
-}
-
-- (void)stderrRedirect:(NSString *)text
+- (void)redirect:(NSString *)text type:(HBRedirectType)type
{
[self write:text];
}
diff --git a/macosx/HBOutputPanelController.h b/macosx/HBOutputPanelController.h
index 32907b02b..2a1b6c282 100644
--- a/macosx/HBOutputPanelController.h
+++ b/macosx/HBOutputPanelController.h
@@ -1,9 +1,8 @@
-/**
- * @file
- * @date 18.5.2007
- *
- * Interface of class HBOutputPanelController.
- */
+/* HBOutputPanelController.h
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
#import <Cocoa/Cocoa.h>
diff --git a/macosx/HBOutputPanelController.m b/macosx/HBOutputPanelController.m
index 3ea4d776f..3cfec6caa 100644
--- a/macosx/HBOutputPanelController.m
+++ b/macosx/HBOutputPanelController.m
@@ -1,15 +1,13 @@
-/**
- * @file
- * @date 18.5.2007
- *
- * Implementation of class HBOutputPanelController.
- */
+/* HBOutputPanelController.m
+
+ This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
#import "HBOutputPanelController.h"
#import "HBOutputRedirect.h"
#import "HBOutputFileWriter.h"
#import "HBUtilities.h"
-#import "project.h"
/// Maximum amount of characters that can be shown in the view.
#define TextStorageUpperSizeLimit 125000
@@ -19,19 +17,17 @@
#define TextStorageLowerSizeLimit 120000
@interface HBOutputPanelController () <HBOutputRedirectListening>
-{
- /// Textview that displays debug output.
- IBOutlet NSTextView *textView;
- /// Text storage for the debug output.
- NSTextStorage *outputTextStorage;
-}
+/// Textview that displays debug output.
+@property (nonatomic, unsafe_unretained) IBOutlet NSTextView *textView;
+
+/// Text storage for the debug output.
+@property (nonatomic, readonly) NSTextStorage *outputTextStorage;
+@property (nonatomic, readonly) NSDictionary *textAttributes;
/// Path to log text file.
@property (nonatomic, copy, readonly) HBOutputFileWriter *outputFile;
-@property (nonatomic, readonly) NSDictionary *textAttributes;
-
@end
@implementation HBOutputPanelController
@@ -43,101 +39,90 @@
{
if( (self = [super initWithWindowNibName:@"OutputPanel"]) )
{
- /* NSWindowController likes to lazily load its window nib. Since this
- * controller tries to touch the outlets before accessing the window, we
- * need to force it to load immediately by invoking its accessor.
- *
- * If/when we switch to using bindings, this can probably go away.
- */
- (void)[self window];
+ // We initialize the outputTextStorage object for the activity window
+ _outputTextStorage = [[NSTextStorage alloc] init];
+
+ // Text attributes
+ _textAttributes = @{NSForegroundColorAttributeName: NSColor.textColor};
- // Additionally, redirect the output to a file on the disk.
- NSURL *outputLogFile = [[HBUtilities appSupportURL] URLByAppendingPathComponent:@"HandBrake-activitylog.txt"];
+ // Add ourself as stderr/stdout listener
+ [HBOutputRedirect.stderrRedirect addListener:self queue:dispatch_get_main_queue()];
+ [HBOutputRedirect.stdoutRedirect addListener:self queue:dispatch_get_main_queue()];
+
+ // Redirect the output to a file on the disk.
+ NSURL *outputLogFile = [HBUtilities.appSupportURL URLByAppendingPathComponent:@"HandBrake-activitylog.txt"];
_outputFile = [[HBOutputFileWriter alloc] initWithFileURL:outputLogFile];
if (_outputFile)
{
- [[HBOutputRedirect stderrRedirect] addListener:_outputFile];
- [[HBOutputRedirect stdoutRedirect] addListener:_outputFile];
+ [HBOutputRedirect.stderrRedirect addListener:_outputFile queue:dispatch_get_main_queue()];
+ [HBOutputRedirect.stdoutRedirect addListener:_outputFile queue:dispatch_get_main_queue()];
}
- // We initialize the outputTextStorage object for the activity window
- outputTextStorage = [[NSTextStorage alloc] init];
- [[textView layoutManager] replaceTextStorage:outputTextStorage];
- [[textView enclosingScrollView] setLineScroll:10];
- [[textView enclosingScrollView] setPageScroll:20];
-
- // Text attributes
- _textAttributes = @{NSForegroundColorAttributeName: [NSColor textColor]};
-
- // Add ourself as stderr/stdout listener
- [[HBOutputRedirect stderrRedirect] addListener:self];
- [[HBOutputRedirect stdoutRedirect] addListener:self];
-
- // Lets report the HandBrake version number here to the activity log and text log file
- NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
- NSString *versionStringFull = [NSString stringWithFormat:@"Handbrake Version: %@ (%@)", infoDict[@"CFBundleShortVersionString"], infoDict[@"CFBundleVersion"]];
- [HBUtilities writeToActivityLog: "%s", versionStringFull.UTF8String];
-
- // Lets also report the hardening status to the activity log, if enabled
-#if HB_PROJECT_HOST_HARDEN == 1
- [HBUtilities writeToActivityLog:"Compile-time hardening features are enabled"];
-#endif
+ [self writeHeader];
}
return self;
}
-/**
- * Stops redirection of stderr and releases resources.
- */
- (void)dealloc
{
- [[HBOutputRedirect stderrRedirect] removeListener:self];
- [[HBOutputRedirect stdoutRedirect] removeListener:self];
+ [HBOutputRedirect.stderrRedirect removeListener:self];
+ [HBOutputRedirect.stdoutRedirect removeListener:self];
+}
+
+- (void)windowDidLoad
+{
+ [super windowDidLoad];
+
+ [_textView.layoutManager replaceTextStorage:_outputTextStorage];
+ [_textView.enclosingScrollView setLineScroll:10];
+ [_textView.enclosingScrollView setPageScroll:20];
+
+ [_textView scrollToEndOfDocument:self];
}
-/**
- * Loads output panel from OutputPanel.nib and shows it.
- */
- (IBAction)showWindow:(id)sender
{
- [textView scrollToEndOfDocument:self];
+ [_textView scrollToEndOfDocument:self];
[super showWindow:sender];
}
+- (void)writeHeader
+{
+ // Lets report the HandBrake version number here to the activity log and text log file
+ NSDictionary *infoDict = NSBundle.mainBundle.infoDictionary;
+ NSString *versionStringFull = [NSString stringWithFormat:@"Handbrake Version: %@ (%@)", infoDict[@"CFBundleShortVersionString"], infoDict[@"CFBundleVersion"]];
+ [HBUtilities writeToActivityLog:"%s", versionStringFull.UTF8String];
+}
+
/**
* Displays text received from HBOutputRedirect in the text view
- * and write it to the log files.
*/
-- (void)stderrRedirect:(NSString *)text
+- (void)redirect:(NSString *)text type:(HBRedirectType)type
{
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:_textAttributes];
- /* Actually write the libhb output to the text view (outputTextStorage) */
- [outputTextStorage appendAttributedString:attributedString];
+ // Actually write the libhb output to the text view (outputTextStorage)
+ [_outputTextStorage appendAttributedString:attributedString];
- /* remove text from outputTextStorage as defined by TextStorageUpperSizeLimit and TextStorageLowerSizeLimit */
- if (outputTextStorage.length > TextStorageUpperSizeLimit)
+ // remove text from outputTextStorage as defined by TextStorageUpperSizeLimit and TextStorageLowerSizeLimit */
+ if (_outputTextStorage.length > TextStorageUpperSizeLimit)
{
- [outputTextStorage deleteCharactersInRange:NSMakeRange(0, [outputTextStorage length] - TextStorageLowerSizeLimit)];
+ [_outputTextStorage deleteCharactersInRange:NSMakeRange(0, _outputTextStorage.length - TextStorageLowerSizeLimit)];
}
- if (self.window.isVisible)
+ if (self.windowLoaded && self.window.isVisible)
{
- [textView scrollToEndOfDocument:self];
+ [_textView scrollToEndOfDocument:self];
}
}
-- (void)stdoutRedirect:(NSString *)text { [self stderrRedirect:text]; }
/**
* Clears the output window.
*/
- (IBAction)clearOutput:(id)sender
{
- [outputTextStorage deleteCharactersInRange:NSMakeRange(0, [outputTextStorage length])];
- /* We want to rewrite the app version info to the top of the activity window so it is always present */
- time_t _now = time( NULL );
- struct tm * now = localtime( &_now );
- fprintf(stderr, "[%02d:%02d:%02d] macgui: %s\n", now->tm_hour, now->tm_min, now->tm_sec, [[HBUtilities handBrakeVersion] UTF8String]);
+ [_outputTextStorage deleteCharactersInRange:NSMakeRange(0, _outputTextStorage.length)];
+ [self writeHeader];
}
/**
@@ -145,9 +130,9 @@
*/
- (IBAction)copyAllOutputToPasteboard:(id)sender
{
- NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+ NSPasteboard *pboard = NSPasteboard.generalPasteboard;
[pboard declareTypes:@[NSPasteboardTypeString] owner:nil];
- [pboard setString:[outputTextStorage string] forType:NSPasteboardTypeString];
+ [pboard setString:_outputTextStorage.string forType:NSPasteboardTypeString];
}
/**
@@ -155,8 +140,8 @@
*/
- (IBAction)openActivityLogFile:(id)sender
{
- /* Opens the activity window log file in the users default text editor */
- [[NSWorkspace sharedWorkspace] openURL:self.outputFile.url];
+ // Opens the activity window log file in the users default text editor
+ [NSWorkspace.sharedWorkspace openURL:self.outputFile.url];
}
/**
@@ -164,16 +149,16 @@
*/
- (IBAction)openEncodeLogDirectory:(id)sender
{
- /* Opens the activity window log file in the users default text editor */
- NSURL *encodeLogDirectory = [[HBUtilities appSupportURL] URLByAppendingPathComponent:@"EncodeLogs"];
- if( ![[NSFileManager defaultManager] fileExistsAtPath:encodeLogDirectory.path] )
+ // Opens the activity window log file in the users default text editor
+ NSURL *encodeLogDirectory = [HBUtilities.appSupportURL URLByAppendingPathComponent:@"EncodeLogs"];
+ if (![NSFileManager.defaultManager fileExistsAtPath:encodeLogDirectory.path])
{
- [[NSFileManager defaultManager] createDirectoryAtPath:encodeLogDirectory.path
- withIntermediateDirectories:NO
- attributes:nil
- error:nil];
+ [NSFileManager.defaultManager createDirectoryAtPath:encodeLogDirectory.path
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:nil];
}
- [[NSWorkspace sharedWorkspace] openURL:encodeLogDirectory];
+ [NSWorkspace.sharedWorkspace openURL:encodeLogDirectory];
}
- (IBAction)clearActivityLogFile:(id)sender
diff --git a/macosx/HBOutputRedirect.h b/macosx/HBOutputRedirect.h
index 6c1fc718c..8a429f9ff 100644
--- a/macosx/HBOutputRedirect.h
+++ b/macosx/HBOutputRedirect.h
@@ -6,16 +6,10 @@
*/
#import <Foundation/Foundation.h>
+#import "HBRedirect.h"
NS_ASSUME_NONNULL_BEGIN
-@protocol HBOutputRedirectListening <NSObject>
-
-- (void)stdoutRedirect:(NSString *)text;
-- (void)stderrRedirect:(NSString *)text;
-
-@end
-
/**
* This class is used to redirect @c stdout and @c stderr outputs. It is never
* created directly; @c stdoutRedirect and @c stderrRedirect class methods
@@ -27,13 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
* universal redirecting is needed, it can be done at file descriptor
* level.
*/
-@interface HBOutputRedirect : NSObject
-
-+ (instancetype)stdoutRedirect;
-+ (instancetype)stderrRedirect;
-
-- (void)addListener:(id <HBOutputRedirectListening>)aListener;
-- (void)removeListener:(id <HBOutputRedirectListening>)aListener;
+@interface HBOutputRedirect : HBRedirect
@end
diff --git a/macosx/HBOutputRedirect.m b/macosx/HBOutputRedirect.m
index 9aff9eb31..6e94c3747 100644
--- a/macosx/HBOutputRedirect.m
+++ b/macosx/HBOutputRedirect.m
@@ -17,28 +17,13 @@ static int stdoutwrite(void *inFD, const char *buffer, int size);
static int stderrwrite(void *inFD, const char *buffer, int size);
@interface HBOutputRedirect ()
-{
- /// Set that contains all registered listeners for this output.
- NSMutableSet *listeners;
-
- /// Selector that is called on listeners to forward the output.
- SEL forwardingSelector;
-
- /// Output stream (@c stdout or @c stderr) redirected by this object.
- FILE *stream;
-
- /// Pointer to old write function for the stream.
- int (*oldWriteFunc)(void *, const char *, int);
-}
-@end
+/// Output stream (@c stdout or @c stderr) redirected by this object.
+@property (nonatomic, readonly) FILE *stream;
+/// Pointer to old write function for the stream.
+@property (nonatomic, readonly) int (*oldWriteFunc)(void *, const char *, int);
-@interface HBOutputRedirect (Private)
-- (instancetype)initWithStream:(FILE *)aStream selector:(SEL)aSelector;
-- (void)startRedirect;
-- (void)stopRedirect;
-- (void)forwardOutput:(NSData *)data;
@end
/**
@@ -48,8 +33,11 @@ int stdoutwrite(void *inFD, const char *buffer, int size)
{
@autoreleasepool
{
- NSData *data = [[NSData alloc] initWithBytes:buffer length:size];
- [g_stdoutRedirect performSelectorOnMainThread:@selector(forwardOutput:) withObject:data waitUntilDone:NO];
+ NSString *string = [[NSString alloc] initWithBytes:buffer length:size encoding:NSUTF8StringEncoding];
+ if (string)
+ {
+ [g_stdoutRedirect forwardOutput:string];
+ }
}
return size;
}
@@ -58,8 +46,11 @@ int stderrwrite(void *inFD, const char *buffer, int size)
{
@autoreleasepool
{
- NSData *data = [[NSData alloc] initWithBytes:buffer length:size];
- [g_stderrRedirect performSelectorOnMainThread:@selector(forwardOutput:) withObject:data waitUntilDone:NO];
+ NSString *string = [[NSString alloc] initWithBytes:buffer length:size encoding:NSUTF8StringEncoding];
+ if (string)
+ {
+ [g_stderrRedirect forwardOutput:string];
+ }
}
return size;
}
@@ -72,8 +63,9 @@ int stderrwrite(void *inFD, const char *buffer, int size)
+ (instancetype)stdoutRedirect
{
if (!g_stdoutRedirect)
- g_stdoutRedirect = [[HBOutputRedirect alloc] initWithStream:stdout selector:@selector(stdoutRedirect:)];
-
+ {
+ g_stdoutRedirect = [[HBOutputRedirect alloc] initWithStream:stdout type:HBRedirectTypeOutput];
+ }
return g_stdoutRedirect;
}
@@ -83,73 +75,27 @@ int stderrwrite(void *inFD, const char *buffer, int size)
+ (instancetype)stderrRedirect
{
if (!g_stderrRedirect)
- g_stderrRedirect = [[HBOutputRedirect alloc] initWithStream:stderr selector:@selector(stderrRedirect:)];
-
+ {
+ g_stderrRedirect = [[HBOutputRedirect alloc] initWithStream:stderr type:HBRedirectTypeError];
+ }
return g_stderrRedirect;
}
/**
- * Adds specified object as listener for this output. Method @c stdoutRedirect:
- * or @c stderrRedirect: of the listener is called to redirect the output.
- */
-- (void)addListener:(id <HBOutputRedirectListening>)aListener
-{
- NSAssert2([aListener respondsToSelector:forwardingSelector], @"Object %@ doesn't respond to selector \"%@\"", aListener, NSStringFromSelector(forwardingSelector));
-
- if (![listeners containsObject:aListener])
- {
- [listeners addObject:aListener];
- }
-
- if ([listeners count] > 0)
- [self startRedirect];
-}
-
-/**
- * Stops forwarding for this output to the specified listener object.
- */
-- (void)removeListener:(id <HBOutputRedirectListening>)aListener
-{
- if ([listeners containsObject:aListener])
- {
- [listeners removeObject:aListener];
- }
-
- // If last listener is removed, stop redirecting output and autorelease
- // self. Remember to set proper global pointer to NULL so the object is
- // recreated again when needed.
- if ([listeners count] == 0)
- {
- [self stopRedirect];
-
- if (self == g_stdoutRedirect)
- g_stdoutRedirect = nil;
- else if (self == g_stderrRedirect)
- g_stderrRedirect = nil;
- }
-}
-
-@end
-
-@implementation HBOutputRedirect (Private)
-
-/**
* Private constructor which should not be called from outside. This is used to
* initialize the class at @c stdoutRedirect and @c stderrRedirect.
*
- * @param aStream Stream that will be redirected (stdout or stderr).
- * @param aSelector Selector that will be called in listeners to redirect the stream.
+ * @param stream Stream that will be redirected (stdout or stderr).
+ * @param type Type that will be called in listeners to redirect the stream.
*
* @return New HBOutputRedirect object.
*/
-- (instancetype)initWithStream:(FILE *)aStream selector:(SEL)aSelector
+- (instancetype)initWithStream:(FILE *)stream type:(HBRedirectType)type
{
- if (self = [super init])
+ if (self = [self initWithType:type])
{
- listeners = [[NSMutableSet alloc] init];
- forwardingSelector = aSelector;
- stream = aStream;
- oldWriteFunc = NULL;
+ _stream = stream;
+ _oldWriteFunc = NULL;
}
return self;
}
@@ -161,10 +107,10 @@ int stderrwrite(void *inFD, const char *buffer, int size)
*/
- (void)startRedirect
{
- if (!oldWriteFunc)
+ if (!_oldWriteFunc)
{
- oldWriteFunc = stream->_write;
- stream->_write = stream == stdout ? stdoutwrite : stderrwrite;
+ _oldWriteFunc = _stream->_write;
+ _stream->_write = _stream == stdout ? stdoutwrite : stderrwrite;
}
}
@@ -174,24 +120,11 @@ int stderrwrite(void *inFD, const char *buffer, int size)
*/
- (void)stopRedirect
{
- if (oldWriteFunc)
+ if (_oldWriteFunc)
{
- stream->_write = oldWriteFunc;
- oldWriteFunc = NULL;
+ _stream->_write = _oldWriteFunc;
+ _oldWriteFunc = NULL;
}
}
-/**
- * Called from @c stdoutwrite() and @c stderrwrite() to forward the output to
- * listeners.
- */
-- (void)forwardOutput:(NSData *)data
-{
- NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- if (string)
- {
- [listeners makeObjectsPerformSelector:forwardingSelector withObject:string];
- }
-}
-
@end
diff --git a/macosx/HBQueue.h b/macosx/HBQueue.h
index d1205b6fe..036df8d27 100644
--- a/macosx/HBQueue.h
+++ b/macosx/HBQueue.h
@@ -6,13 +6,15 @@
#import <Foundation/Foundation.h>
-#import "HBCore.h"
#import "HBDistributedArray.h"
#import "HBQueueItem.h"
#import "HBJobOutputFileWriter.h"
NS_ASSUME_NONNULL_BEGIN
+extern NSString * const HBQueueDidChangeStateNotification;
+extern NSString * const HBQueueNotificationStateKey; // HBState
+
extern NSString * const HBQueueDidAddItemNotification;
extern NSString * const HBQueueDidRemoveItemNotification;
extern NSString * const HBQueueDidChangeItemNotification;
@@ -45,11 +47,9 @@ extern NSString * const HBQueueItemNotificationItemKey; // HBQueueI
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithURL:(NSURL *)queueURL;
-@property (nonatomic, readonly) HBCore *core;
@property (nonatomic, readonly) HBDistributedArray<HBQueueItem *> *items;
@property (nonatomic, nullable) HBQueueItem *currentItem;
-@property (nonatomic, nullable) HBJobOutputFileWriter *currentLog;
@property (nonatomic) NSUInteger pendingItemsCount;
@property (nonatomic) NSUInteger failedItemsCount;
diff --git a/macosx/HBQueue.m b/macosx/HBQueue.m
index 498905f17..7e285c185 100644
--- a/macosx/HBQueue.m
+++ b/macosx/HBQueue.m
@@ -5,8 +5,15 @@
It may be used under the terms of the GNU General Public License. */
#import "HBQueue.h"
-#import "NSArray+HBAdditions.h"
+#import "HBRemoteCore.h"
+
#import "HBPreferencesKeys.h"
+#import "NSArray+HBAdditions.h"
+
+static void *HBQueueContext = &HBQueueContext;
+
+NSString * const HBQueueDidChangeStateNotification = @"HBQueueDidChangeStateNotification";
+NSString * const HBQueueNotificationStateKey = @"HBQueueNotificationStateKey";
NSString * const HBQueueDidAddItemNotification = @"HBQueueDidAddItemNotification";
NSString * const HBQueueDidRemoveItemNotification = @"HBQueueDidRemoveItemNotification";
@@ -38,8 +45,11 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
@interface HBQueue ()
+@property (nonatomic, readonly) HBRemoteCore *core;
@property (nonatomic) BOOL stop;
+@property (nonatomic, nullable) HBJobOutputFileWriter *currentLog;
+
@end
@implementation HBQueue
@@ -52,7 +62,7 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
NSInteger loggingLevel = [NSUserDefaults.standardUserDefaults integerForKey:HBLoggingLevel];
// Init a separate instance of libhb for the queue
- _core = [[HBCore alloc] initWithLogLevel:loggingLevel name:@"QueueCore"];
+ _core = [[HBRemoteCore alloc] initWithLogLevel:loggingLevel name:@"QueueCore"];
_core.automaticallyPreventSleep = NO;
_items = [[HBDistributedArray alloc] initWithURL:queueURL class:[HBQueueItem class]];
@@ -62,10 +72,28 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadQueue) name:HBDistributedArrayChanged object:_items];
[self updateStats];
+
+ // Set up observers
+ [self.core addObserver:self forKeyPath:@"state"
+ options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
+ context:HBQueueContext];
+
}
return self;
}
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ if (context == HBQueueContext)
+ {
+ [NSNotificationCenter.defaultCenter postNotificationName:HBQueueDidChangeStateNotification object:self userInfo:@{HBQueueNotificationStateKey: @(self.core.state)}];
+ }
+ else
+ {
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ }
+}
+
#pragma mark - Public methods
- (void)addJob:(HBJob *)item
@@ -466,6 +494,8 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
self.pendingItemsCount = pendingCount;
self.failedItemsCount = failedCount;
self.completedItemsCount = completedCount;
+
+ [NSNotificationCenter.defaultCenter postNotificationName:HBQueueDidChangeStateNotification object:self userInfo:@{HBQueueNotificationStateKey: @(self.core.state)}];
}
- (BOOL)isDiskSpaceLowAtURL:(NSURL *)url
@@ -563,8 +593,9 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
self.currentLog = [[HBJobOutputFileWriter alloc] initWithJob:nextItem.job];
if (self.currentLog)
{
- [[HBOutputRedirect stderrRedirect] addListener:self.currentLog];
- [[HBOutputRedirect stdoutRedirect] addListener:self.currentLog];
+ dispatch_queue_t mainQueue = dispatch_get_main_queue();
+ [self.core.stderrRedirect addListener:self.currentLog queue:mainQueue];
+ [self.core.stdoutRedirect addListener:self.currentLog queue:mainQueue];
}
self.currentItem = nextItem;
@@ -601,8 +632,8 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
// Since we are done with this encode, tell output to stop writing to the
// individual encode log.
- [[HBOutputRedirect stderrRedirect] removeListener:self.currentLog];
- [[HBOutputRedirect stdoutRedirect] removeListener:self.currentLog];
+ [self.core.stderrRedirect removeListener:self.currentLog];
+ [self.core.stdoutRedirect removeListener:self.currentLog];
self.currentLog = nil;
@@ -693,14 +724,11 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
HBJob *job = item.job;
- // Reset the title in the job.
- job.title = self.core.titles.firstObject;
-
NSParameterAssert(job);
HBStateFormatter *formatter = [[HBStateFormatter alloc] init];
formatter.twoLines = NO;
- self.core.stateFormatter = formatter;
+ //self.core.stateFormatter = formatter;
// Progress handler
void (^progressHandler)(HBState state, HBProgress progress, NSString *info) = ^(HBState state, HBProgress progress, NSString *info)
@@ -739,9 +767,6 @@ NSString * const HBQueueItemNotificationItemKey = @"HBQueueItemNotificationItemK
// We should be all setup so let 'er rip
[self.core encodeJob:job progressHandler:progressHandler completionHandler:completionHandler];
-
- // We are done using the title, remove it from the job
- job.title = nil;
}
/**
diff --git a/macosx/HBQueueController.m b/macosx/HBQueueController.m
index 196495a7d..4de78e300 100644
--- a/macosx/HBQueueController.m
+++ b/macosx/HBQueueController.m
@@ -20,8 +20,6 @@
@import HandBrakeKit;
-static void *HBControllerQueueCoreContext = &HBControllerQueueCoreContext;
-
@interface HBQueueController () <NSUserNotificationCenterDelegate, HBQueueTableViewControllerDelegate, HBQueueDetailsViewControllerDelegate>
@property (weak) IBOutlet NSSplitView *splitView;
@@ -154,51 +152,41 @@ static void *HBControllerQueueCoreContext = &HBControllerQueueCoreContext;
[self.window setFrameFromString:@"HBQueueWindowFrameAutosave"];
// Set up observers
- [self.queue.core addObserver:self forKeyPath:@"state"
- options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
- context:HBControllerQueueCoreContext];
- [self.queue addObserver:self forKeyPath:@"pendingItemsCount"
- options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
- context:HBControllerQueueCoreContext];
+ [NSNotificationCenter.defaultCenter addObserverForName:HBQueueDidChangeStateNotification object:_queue queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull note) {
+ [self updateUI];
+ }];
[self tableViewDidSelectItemsAtIndexes:[NSIndexSet indexSet]];
}
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+- (void)updateUI
{
- if (context == HBControllerQueueCoreContext)
- {
- [self updateToolbarButtonsState];
- [self.window.toolbar validateVisibleItems];
+ [self updateToolbarButtonsState];
+ [self.window.toolbar validateVisibleItems];
- if (@available(macOS 10.12.2, *))
- {
- [self _touchBar_updateButtonsState];
- [self _touchBar_validateUserInterfaceItems];
- }
+ if (@available(macOS 10.12.2, *))
+ {
+ [self _touchBar_updateButtonsState];
+ [self _touchBar_validateUserInterfaceItems];
+ }
- NSString *string;
- if (self.queue.pendingItemsCount == 0)
+ NSString *string;
+ if (self.queue.pendingItemsCount == 0)
+ {
+ self.window.title = NSLocalizedString(@"Queue", @"Queue window title");
+ }
+ else
+ {
+ if (self.queue.pendingItemsCount == 1)
{
- self.window.title = NSLocalizedString(@"Queue", @"Queue window title");
+ string = [NSString stringWithFormat: NSLocalizedString(@"%d encode pending", @"Queue status"), self.queue.pendingItemsCount];
}
else
{
- if (self.queue.pendingItemsCount == 1)
- {
- string = [NSString stringWithFormat: NSLocalizedString(@"%d encode pending", @"Queue status"), self.queue.pendingItemsCount];
- }
- else
- {
- string = [NSString stringWithFormat: NSLocalizedString(@"%d encodes pending", @"Queue status"), self.queue.pendingItemsCount];
- }
-
- self.window.title = [NSString stringWithFormat: NSLocalizedString(@"Queue (%@)", @"Queue window title"), string];
+ string = [NSString stringWithFormat: NSLocalizedString(@"%d encodes pending", @"Queue status"), self.queue.pendingItemsCount];
}
- }
- else
- {
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+
+ self.window.title = [NSString stringWithFormat: NSLocalizedString(@"Queue (%@)", @"Queue window title"), string];
}
}
diff --git a/macosx/HBRedirect.h b/macosx/HBRedirect.h
new file mode 100644
index 000000000..3e15df73d
--- /dev/null
+++ b/macosx/HBRedirect.h
@@ -0,0 +1,37 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSUInteger, HBRedirectType) {
+ HBRedirectTypeOutput,
+ HBRedirectTypeError
+};
+
+@protocol HBOutputRedirectListening <NSObject>
+
+- (void)redirect:(NSString *)text type:(HBRedirectType)type;
+
+@end
+
+@interface HBRedirect : NSObject
+
++ (instancetype)stdoutRedirect;
++ (instancetype)stderrRedirect;
+
+- (void)addListener:(id <HBOutputRedirectListening>)aListener queue:(dispatch_queue_t)queue;
+- (void)removeListener:(id <HBOutputRedirectListening>)aListener;
+
+// Methods to subclass
+
+- (instancetype)initWithType:(HBRedirectType)type;
+- (void)forwardOutput:(NSString *)text;
+- (void)startRedirect;
+- (void)stopRedirect;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/macosx/HBRedirect.m b/macosx/HBRedirect.m
new file mode 100644
index 000000000..1b3529bda
--- /dev/null
+++ b/macosx/HBRedirect.m
@@ -0,0 +1,146 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import "HBRedirect.h"
+
+@interface HBOutputRedirectListenerEntry : NSObject
+{
+@public
+ id<HBOutputRedirectListening> listener;
+ dispatch_queue_t queue;
+}
+
+- (instancetype)initWithListener:(id<HBOutputRedirectListening>)listener queue:(dispatch_queue_t)queue;
+
+@end
+
+@implementation HBOutputRedirectListenerEntry
+
+- (instancetype)initWithListener:(id<HBOutputRedirectListening>)entryListener queue:(dispatch_queue_t)entryQueue
+{
+ self = [super init];
+ if (self)
+ {
+ self->listener = entryListener;
+ self->queue = entryQueue;
+ }
+ return self;
+}
+
+@end
+
+@interface HBRedirect ()
+
+/// Set that contains all registered listeners for this output.
+@property (nonatomic, readonly) NSMutableSet<HBOutputRedirectListenerEntry *> *listenerEntries;
+
+/// Selector that is called on listeners to forward the output.
+@property (nonatomic, readonly) HBRedirectType type;
+
+@end
+
+@implementation HBRedirect
+
+/**
+ * Returns HBOutputRedirect object used to redirect stdout.
+ */
++ (instancetype)stdoutRedirect
+{
+ return [[HBRedirect alloc] initWithType:HBRedirectTypeOutput];
+}
+
+/**
+ * Returns HBOutputRedirect object used to redirect stderr.
+ */
++ (instancetype)stderrRedirect
+{
+ return [[HBRedirect alloc] initWithType:HBRedirectTypeError];
+}
+
+- (HBOutputRedirectListenerEntry *)entryForListener:(id <HBOutputRedirectListening>)listener
+{
+ for (HBOutputRedirectListenerEntry *entry in _listenerEntries)
+ {
+ if (entry->listener == listener)
+ {
+ return entry;
+ }
+ }
+ return nil;
+}
+
+- (BOOL)containsListener:(id <HBOutputRedirectListening>)listener
+{
+ HBOutputRedirectListenerEntry *entry = [self entryForListener:listener];
+ return entry && [_listenerEntries containsObject:listener];
+}
+
+/**
+ * Adds specified object as listener for this output. Method @c stdoutRedirect:
+ * or @c stderrRedirect: of the listener is called to redirect the output.
+ */
+- (void)addListener:(id <HBOutputRedirectListening>)listener queue:(dispatch_queue_t)queue
+{
+ NSAssert2([listener respondsToSelector:@selector(redirect:type:)], @"Object %@ doesn't respond to selector \"%@\"", listener, NSStringFromSelector(@selector(redirect:type:)));
+
+ if (![self containsListener:listener])
+ {
+ HBOutputRedirectListenerEntry *entry = [[HBOutputRedirectListenerEntry alloc] initWithListener:listener queue:queue];
+ [_listenerEntries addObject:entry];
+ }
+
+ if (_listenerEntries.count > 0)
+ {
+ [self startRedirect];
+ }
+}
+
+/**
+ * Stops forwarding for this output to the specified listener object.
+ */
+- (void)removeListener:(id <HBOutputRedirectListening>)listener
+{
+ HBOutputRedirectListenerEntry *entry = [self entryForListener:listener];
+ if (entry)
+ {
+ [_listenerEntries removeObject:entry];
+ }
+
+ // If last listener is removed, stop redirecting output and autorelease
+ // self. Remember to set proper global pointer to NULL so the object is
+ // recreated again when needed.
+ if (_listenerEntries.count == 0)
+ {
+ [self stopRedirect];
+ }
+}
+
+- (instancetype)initWithType:(HBRedirectType)type
+{
+ if (self = [super init])
+ {
+ _listenerEntries = [[NSMutableSet alloc] init];
+ _type = type;
+ }
+ return self;
+}
+
+- (void)startRedirect {}
+- (void)stopRedirect {}
+
+/**
+ * Called from @c stdoutwrite() and @c stderrwrite() to forward the output to
+ * listeners.
+ */
+- (void)forwardOutput:(NSString *)string
+{
+ for (HBOutputRedirectListenerEntry *entry in _listenerEntries)
+ {
+ dispatch_async(entry->queue, ^{
+ [entry->listener redirect:string type:self->_type];
+ });
+ }
+}
+
+@end
diff --git a/macosx/HBRemoteCore.h b/macosx/HBRemoteCore.h
new file mode 100644
index 000000000..6bd43c141
--- /dev/null
+++ b/macosx/HBRemoteCore.h
@@ -0,0 +1,40 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Foundation/Foundation.h>
+#import "HBRedirect.h"
+
+@import HandBrakeKit;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HBRemoteCore : NSObject
+
+- (instancetype)initWithLogLevel:(NSInteger)level name:(NSString *)name;
+
+@property (nonatomic, readonly) HBState state;
+
+@property (nonatomic, readonly) HBRedirect *stdoutRedirect;
+@property (nonatomic, readonly) HBRedirect *stderrRedirect;
+
+@property (nonatomic, readwrite) BOOL automaticallyPreventSleep;
+
+- (void)preventSleep;
+- (void)allowSleep;
+
+- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler;
+
+- (void)cancelScan;
+
+- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler;
+
+- (void)cancelEncode;
+
+- (void)pause;
+
+- (void)resume;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/macosx/HBRemoteCore.m b/macosx/HBRemoteCore.m
new file mode 100644
index 000000000..b3db5b37b
--- /dev/null
+++ b/macosx/HBRemoteCore.m
@@ -0,0 +1,167 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import "HBRemoteCore.h"
+#import "HBRemoteCoreProtocol.h"
+
+@import HandBrakeKit;
+
+@interface HBRemoteCore () <HBRemoteProgressProtocol>
+
+@property (nonatomic, readonly) NSXPCConnection *connection;
+
+@property (nonatomic, readonly) id<HBRemoteCoreProtocol> proxy;
+
+@property (nonatomic, readwrite) HBState state;
+
+@property (nonatomic, readwrite, copy) HBCoreProgressHandler progressHandler;
+@property (nonatomic, readwrite, copy) HBCoreCompletionHandler completionHandler;
+
+@end
+
+@implementation HBRemoteCore
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self)
+ {
+ _state = HBStateIdle;
+ _stdoutRedirect = HBRedirect.stdoutRedirect;
+ _stderrRedirect = HBRedirect.stderrRedirect;
+
+ [self connect];
+ }
+ return self;
+}
+
+- (void)connect
+{
+ _connection = [[NSXPCConnection alloc] initWithServiceName:@"fr.handbrake.HandBrakeXPCService"];
+ _connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(HBRemoteCoreProtocol)];
+
+ _connection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(HBRemoteProgressProtocol)];
+ _connection.exportedObject = self;
+
+ _proxy = [_connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
+
+ }];
+
+ [_connection resume];
+}
+
+- (instancetype)initWithLogLevel:(NSInteger)level name:(NSString *)name
+{
+ self = [self init];
+ if (self)
+ {
+ [_proxy setUpWithLogLevel:level name:name];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [_connection.remoteObjectProxy tearDown];
+ [_connection invalidate];
+}
+
+- (void)updateState:(HBState)state {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ self.state = state;
+ });
+}
+
+- (void)setAutomaticallyPreventSleep:(BOOL)automaticallyPreventSleep
+{
+ [_proxy setAutomaticallyPreventSleep:automaticallyPreventSleep];
+}
+
+- (void)allowSleep
+{
+ [_proxy allowSleep];
+}
+
+- (void)preventSleep
+{
+ [_proxy preventSleep];
+}
+
+- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds progressHandler:(nonnull HBCoreProgressHandler)progressHandler completionHandler:(nonnull HBCoreCompletionHandler)completionHandler
+{
+ self.progressHandler = progressHandler;
+ self.completionHandler = completionHandler;
+
+ NSData *bookmark = [url bookmarkDataWithOptions:0 includingResourceValuesForKeys:nil relativeToURL:nil error:NULL];
+ [_connection.remoteObjectProxy provideResourceAccessWithBookmarks:@[bookmark]];
+
+ self.state = HBStateScanning;
+
+ [_connection.remoteObjectProxy scanURL:url titleIndex:index previews:previewsNum minDuration:seconds withReply:^(HBCoreResult result) {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ self.progressHandler = nil;
+ self.completionHandler(result);
+ });
+ }];
+}
+
+- (void)cancelScan
+{
+ [_proxy cancelScan];
+}
+
+- (void)encodeJob:(HBJob *)job progressHandler:(HBCoreProgressHandler)progressHandler completionHandler:(HBCoreCompletionHandler)completionHandler
+{
+ NSData *bookmark = [job.outputURL bookmarkDataWithOptions:0 includingResourceValuesForKeys:nil relativeToURL:nil error:NULL];
+ [_connection.remoteObjectProxy provideResourceAccessWithBookmarks:@[bookmark]];
+
+ self.progressHandler = progressHandler;
+ self.completionHandler = completionHandler;
+
+ self.state = HBStateWorking;
+
+ [_connection.remoteObjectProxy encodeJob:job withReply:^(HBCoreResult result) {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ self.progressHandler = nil;
+ self.completionHandler(result);
+ });
+ }];
+}
+
+- (void)cancelEncode
+{
+ [_proxy cancelEncode];
+}
+
+- (void)updateProgress:(double)currentProgress hours:(int)hours minutes:(int)minutes seconds:(int)seconds state:(HBState)state info:(NSString *)info {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ HBProgress progress = {currentProgress , hours, minutes, seconds};
+ self.state = state;
+ self.progressHandler(state, progress, info);
+ });
+}
+
+- (void)forwardOutput:(NSString *)text
+{
+ [_stdoutRedirect forwardOutput:text];
+ [HBUtilities writeToActivityLogWithNoHeader:text];
+}
+
+- (void)forwardError:(NSString *)text
+{
+ [_stdoutRedirect forwardOutput:text];
+ [HBUtilities writeToActivityLogWithNoHeader:text];
+}
+
+- (void)pause
+{
+ [_proxy pauseEncode];
+}
+
+- (void)resume
+{
+ [_proxy resumeEncode];
+}
+
+@end
diff --git a/macosx/HBStateFormatter.m b/macosx/HBStateFormatter.m
index 90919e84f..7993aaa32 100644
--- a/macosx/HBStateFormatter.m
+++ b/macosx/HBStateFormatter.m
@@ -145,7 +145,10 @@
case HB_STATE_WORKING:
case HB_STATE_PAUSED:
#define p s.param.working
- progress = (p.progress + p.pass - 1) / p.pass_count;
+ if (p.pass_count > 0)
+ {
+ progress = (p.progress + p.pass - 1) / p.pass_count;
+ }
#undef p
break;
diff --git a/macosx/HBSubtitles.m b/macosx/HBSubtitles.m
index dd1d7f981..c31ed233c 100644
--- a/macosx/HBSubtitles.m
+++ b/macosx/HBSubtitles.m
@@ -488,7 +488,7 @@ extern NSString *keySubTrackExternalFileURLBookmark;
_tokens = [NSMutableArray array];
decodeInt(_container); if (_container != HB_MUX_MP4 && _container != HB_MUX_MKV && _container != HB_MUX_WEBM) { goto fail; }
- decodeCollectionOfObjects3(_sourceTracks, NSArray, NSDictionary, NSURL, NSData);
+ decodeCollectionOfObjects5(_sourceTracks, NSArray, NSDictionary, NSURL, NSData, NSString, NSNumber);
#ifdef __SANDBOX_ENABLED__
for (NSDictionary *sourceTrack in _sourceTracks)
diff --git a/macosx/HBSubtitlesDefaults.m b/macosx/HBSubtitlesDefaults.m
index 891f5e6e9..bfbe824c0 100644
--- a/macosx/HBSubtitlesDefaults.m
+++ b/macosx/HBSubtitlesDefaults.m
@@ -230,7 +230,7 @@
{
goto fail;
}
- decodeObjectOrFail(_trackSelectionLanguages, NSMutableArray);
+ decodeCollectionOfObjects(_trackSelectionLanguages, NSMutableArray, NSString);
decodeBool(_addForeignAudioSearch);
decodeBool(_addForeignAudioSubtitle);
diff --git a/macosx/HBUtilities.h b/macosx/HBUtilities.h
index f2d1aa0c8..18f294a01 100644
--- a/macosx/HBUtilities.h
+++ b/macosx/HBUtilities.h
@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param format a standard c format string with varargs.
*/
+ (void)writeToActivityLog:(const char *)format, ...;
++ (void)writeToActivityLogWithNoHeader:(NSString *)text;
+ (nullable NSURL *)URLFromBookmark:(NSData *)bookmark;
+ (nullable NSData *)bookmarkFromURL:(NSURL *)url;
diff --git a/macosx/HBUtilities.m b/macosx/HBUtilities.m
index 9099af552..733226e89 100644
--- a/macosx/HBUtilities.m
+++ b/macosx/HBUtilities.m
@@ -54,6 +54,11 @@
va_end(args);
}
++ (void)writeToActivityLogWithNoHeader:(NSString *)text
+{
+ fprintf(stderr, "%s", text.UTF8String);
+}
+
+ (nullable NSURL *)URLFromBookmark:(NSData *)bookmark
{
NSParameterAssert(bookmark);
diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj
index ff0986a70..9e37b17e7 100644
--- a/macosx/HandBrake.xcodeproj/project.pbxproj
+++ b/macosx/HandBrake.xcodeproj/project.pbxproj
@@ -179,7 +179,7 @@
A91CE2FC1C7DB99D0068F46F /* HBPreset.h in Headers */ = {isa = PBXBuildFile; fileRef = A9CF25F21990D64E0023F727 /* HBPreset.h */; settings = {ATTRIBUTES = (Public, ); }; };
A91CE2FD1C7DB99D0068F46F /* HBMutablePreset.h in Headers */ = {isa = PBXBuildFile; fileRef = A96CD1741BCC5F9100F372F1 /* HBMutablePreset.h */; settings = {ATTRIBUTES = (Public, ); }; };
A91CE2FE1C7DB99D0068F46F /* HBTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = A9D488A31996270300E9B1BA /* HBTreeNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
- A91D54871E378ABD006D0997 /* HBSecurityAccessToken.h in Headers */ = {isa = PBXBuildFile; fileRef = A91D54851E378ABD006D0997 /* HBSecurityAccessToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A91D54871E378ABD006D0997 /* HBSecurityAccessToken.h in Headers */ = {isa = PBXBuildFile; fileRef = A91D54851E378ABD006D0997 /* HBSecurityAccessToken.h */; settings = {ATTRIBUTES = (Public, ); }; };
A91D54881E378ABD006D0997 /* HBSecurityAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = A91D54861E378ABD006D0997 /* HBSecurityAccessToken.m */; };
A91F97351D7B2A4E00D82DCE /* HBAudioTransformers.h in Headers */ = {isa = PBXBuildFile; fileRef = A91F97331D7B2A4E00D82DCE /* HBAudioTransformers.h */; settings = {ATTRIBUTES = (Public, ); }; };
A91F97361D7B2A4E00D82DCE /* HBAudioTransformers.m in Sources */ = {isa = PBXBuildFile; fileRef = A91F97341D7B2A4E00D82DCE /* HBAudioTransformers.m */; };
@@ -200,6 +200,8 @@
A94A98F51C858EFB004BA9BA /* HBDictTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A94A98F41C858EFB004BA9BA /* HBDictTests.m */; };
A94DC2DE20CADA2C00EAC8FD /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = A94DC2DC20CADA2C00EAC8FD /* MainWindow.xib */; };
A95121E61B5F7BE700FD773D /* NSArray+HBAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = A95121E51B5F7BE700FD773D /* NSArray+HBAdditions.m */; };
+ A954010022FF240E00F83A5F /* HBOutputRedirect.m in Sources */ = {isa = PBXBuildFile; fileRef = 273F209E14ADBE670021BE6D /* HBOutputRedirect.m */; };
+ A954010322FF397000F83A5F /* HBRedirect.m in Sources */ = {isa = PBXBuildFile; fileRef = A954010222FF397000F83A5F /* HBRedirect.m */; };
A955128B1A320B02001BFC6F /* libjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A95512881A320A12001BFC6F /* libjansson.a */; };
A957EBCD218DBE5900007988 /* HBAutoNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = A957EBCC218DBE5900007988 /* HBAutoNamer.m */; };
A958EAC222E24D6400D83AF4 /* HBQueueTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = A958EAC422E24D6400D83AF4 /* HBQueueTableViewController.xib */; };
@@ -210,6 +212,10 @@
A95BC1E81CD2548A008D6A33 /* volLowTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = A95BC1E61CD2548A008D6A33 /* volLowTemplate.pdf */; };
A96127DF22E0994E0086E6DC /* HBQueueInfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96127DD22E0994E0086E6DC /* HBQueueInfoViewController.m */; };
A96127E422E09ADD0086E6DC /* HBQueueTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96127E222E09ADD0086E6DC /* HBQueueTableViewController.m */; };
+ A964D39A22FDE8EE00DFCAEA /* HandBrakeXPCService.m in Sources */ = {isa = PBXBuildFile; fileRef = A964D39922FDE8EE00DFCAEA /* HandBrakeXPCService.m */; };
+ A964D39C22FDE8EE00DFCAEA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A964D39B22FDE8EE00DFCAEA /* main.m */; };
+ A964D3A022FDE8EE00DFCAEA /* HandBrakeXPCService.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = A964D39522FDE8EE00DFCAEA /* HandBrakeXPCService.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ A964D3A822FDE91B00DFCAEA /* HBRemoteCore.m in Sources */ = {isa = PBXBuildFile; fileRef = A964D3A722FDE91B00DFCAEA /* HBRemoteCore.m */; };
A96664B01CCE45BF00DA4A57 /* HBPlayerHUDController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96664AE1CCE45BF00DA4A57 /* HBPlayerHUDController.m */; };
A96664B51CCE48F700DA4A57 /* HBPictureHUDController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96664B31CCE48F700DA4A57 /* HBPictureHUDController.m */; };
A96664BA1CCE493D00DA4A57 /* HBEncodingProgressHUDController.m in Sources */ = {isa = PBXBuildFile; fileRef = A96664B81CCE493D00DA4A57 /* HBEncodingProgressHUDController.m */; };
@@ -232,6 +238,7 @@
A98B8E241C7DD2A200B810C9 /* HBPresetCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = A997D8EB1A4ABB0900E19B6F /* HBPresetCoding.h */; settings = {ATTRIBUTES = (Public, ); }; };
A98C29C41977B10600AF5DED /* HBLanguagesSelection.m in Sources */ = {isa = PBXBuildFile; fileRef = A98C29C31977B10600AF5DED /* HBLanguagesSelection.m */; };
A9906B2C1A710920001D82D5 /* HBQueueController.m in Sources */ = {isa = PBXBuildFile; fileRef = A9906B2B1A710920001D82D5 /* HBQueueController.m */; };
+ A990C55322FF4FBA00E07CE2 /* HandBrakeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9736F021C7DA5FE008F1D18 /* HandBrakeKit.framework */; };
A99F40CF1B624E7E00750170 /* HBPictureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A99F40CD1B624E7E00750170 /* HBPictureViewController.m */; };
A9A0CBE81CCEA3670045B3DF /* HBPlayerTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = A9A0CBE61CCEA1D10045B3DF /* HBPlayerTrack.m */; };
A9A25D9C21182741005A8A0F /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9A25D9B21182741005A8A0F /* CoreMedia.framework */; };
@@ -265,6 +272,7 @@
A9ABD1A91E2A0F8200EC8B65 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9ABD1A81E2A0F8200EC8B65 /* CoreGraphics.framework */; };
A9ABD1AA1E2A0F8F00EC8B65 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9ABD1A81E2A0F8200EC8B65 /* CoreGraphics.framework */; };
A9B3B63922E2EA58001CEB9A /* HBQueueItemWorkingView.m in Sources */ = {isa = PBXBuildFile; fileRef = A9B3B63822E2EA58001CEB9A /* HBQueueItemWorkingView.m */; };
+ A9B5568522FFE4870050D582 /* HBRedirect.m in Sources */ = {isa = PBXBuildFile; fileRef = A954010222FF397000F83A5F /* HBRedirect.m */; };
A9B6B9EE217B38D200B957AE /* HBLocalizationUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B6B9ED217B38D200B957AE /* HBLocalizationUtilities.h */; };
A9B6B9F1217B408E00B957AE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A9B6B9EF217B408E00B957AE /* InfoPlist.strings */; };
A9B6B9F4217B408E00B957AE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A9B6B9F2217B408E00B957AE /* Localizable.strings */; };
@@ -307,6 +315,13 @@
remoteGlobalIDString = 273F203814ADBC200021BE6D;
remoteInfo = HandBrake;
};
+ A964D39E22FDE8EE00DFCAEA /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 273F1FE014AD9DA40021BE6D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A964D39422FDE8EE00DFCAEA;
+ remoteInfo = HandBrakeXPCService;
+ };
A96A4F85217A4C8900755E35 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 273F1FE014AD9DA40021BE6D /* Project object */;
@@ -366,6 +381,7 @@
files = (
A939855622315638001DCAEB /* org.sparkle-project.InstallerConnection.xpc in CopyFiles */,
A939855722315638001DCAEB /* org.sparkle-project.InstallerLauncher.xpc in CopyFiles */,
+ A964D3A022FDE8EE00DFCAEA /* HandBrakeXPCService.xpc in CopyFiles */,
A939855822315638001DCAEB /* org.sparkle-project.InstallerStatus.xpc in CopyFiles */,
A939855A22315993001DCAEB /* org.sparkle-project.Downloader.xpc in CopyFiles */,
);
@@ -410,7 +426,6 @@
273F209814ADBE670021BE6D /* HBDVDDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBDVDDetector.m; sourceTree = "<group>"; };
273F209B14ADBE670021BE6D /* HBOutputPanelController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBOutputPanelController.h; sourceTree = "<group>"; };
273F209C14ADBE670021BE6D /* HBOutputPanelController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBOutputPanelController.m; sourceTree = "<group>"; };
- 273F209D14ADBE670021BE6D /* HBOutputRedirect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBOutputRedirect.h; sourceTree = "<group>"; };
273F209E14ADBE670021BE6D /* HBOutputRedirect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBOutputRedirect.m; sourceTree = "<group>"; };
273F209F14ADBE670021BE6D /* HBPreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBPreferencesController.h; sourceTree = "<group>"; };
273F20A014ADBE670021BE6D /* HBPreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBPreferencesController.m; sourceTree = "<group>"; };
@@ -553,6 +568,8 @@
A9537BF71A48AC9000141102 /* HBFilters+UIAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBFilters+UIAdditions.h"; sourceTree = "<group>"; };
A9537BF81A48AC9000141102 /* HBFilters+UIAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBFilters+UIAdditions.m"; sourceTree = "<group>"; };
A953FF3820CAD29300325A51 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/HBSummaryViewController.xib; sourceTree = "<group>"; };
+ A954010122FF397000F83A5F /* HBRedirect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBRedirect.h; sourceTree = "<group>"; };
+ A954010222FF397000F83A5F /* HBRedirect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBRedirect.m; sourceTree = "<group>"; };
A95512881A320A12001BFC6F /* libjansson.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjansson.a; path = external/contrib/lib/libjansson.a; sourceTree = BUILT_PRODUCTS_DIR; };
A957EBCB218DBE5900007988 /* HBAutoNamer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBAutoNamer.h; sourceTree = "<group>"; };
A957EBCC218DBE5900007988 /* HBAutoNamer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBAutoNamer.m; sourceTree = "<group>"; };
@@ -597,6 +614,14 @@
A9637DA820F7A252001EAE7C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/HBPictureViewController.strings; sourceTree = "<group>"; };
A9637DA920F7A252001EAE7C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/HBPlayerHUDController.strings; sourceTree = "<group>"; };
A9637DAA20F7A252001EAE7C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/ChaptersTitles.strings; sourceTree = "<group>"; };
+ A964D39522FDE8EE00DFCAEA /* HandBrakeXPCService.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = HandBrakeXPCService.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
+ A964D39722FDE8EE00DFCAEA /* HBRemoteCoreProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBRemoteCoreProtocol.h; sourceTree = "<group>"; };
+ A964D39822FDE8EE00DFCAEA /* HandBrakeXPCService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HandBrakeXPCService.h; sourceTree = "<group>"; };
+ A964D39922FDE8EE00DFCAEA /* HandBrakeXPCService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HandBrakeXPCService.m; sourceTree = "<group>"; };
+ A964D39B22FDE8EE00DFCAEA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ A964D39D22FDE8EE00DFCAEA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ A964D3A622FDE91A00DFCAEA /* HBRemoteCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBRemoteCore.h; sourceTree = "<group>"; };
+ A964D3A722FDE91B00DFCAEA /* HBRemoteCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBRemoteCore.m; sourceTree = "<group>"; };
A96664AD1CCE45BF00DA4A57 /* HBPlayerHUDController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBPlayerHUDController.h; sourceTree = "<group>"; };
A96664AE1CCE45BF00DA4A57 /* HBPlayerHUDController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBPlayerHUDController.m; sourceTree = "<group>"; };
A96664B21CCE48F700DA4A57 /* HBPictureHUDController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBPictureHUDController.h; sourceTree = "<group>"; };
@@ -638,6 +663,7 @@
A98F38041C7DCA7E00E469C8 /* HBStateFormatter+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBStateFormatter+Private.h"; sourceTree = "<group>"; };
A98FD5941B19C6E400FCC7A5 /* HBTitle+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBTitle+Private.h"; sourceTree = "<group>"; };
A9906B2B1A710920001D82D5 /* HBQueueController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBQueueController.m; sourceTree = "<group>"; };
+ A990C55222FF4EBA00E07CE2 /* HandBrakeXPCService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HandBrakeXPCService.entitlements; sourceTree = "<group>"; };
A990D9051A64562200139032 /* HBJob+HBJobConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HBJob+HBJobConversion.h"; sourceTree = "<group>"; };
A990D9061A64562200139032 /* HBJob+HBJobConversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "HBJob+HBJobConversion.m"; sourceTree = "<group>"; };
A99422DE1B1887B000DDB077 /* NSJSONSerialization+HBAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSJSONSerialization+HBAdditions.h"; sourceTree = "<group>"; };
@@ -685,6 +711,7 @@
A9B34D74197696FE00871B7D /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = System/Library/Frameworks/DiskArbitration.framework; sourceTree = SDKROOT; };
A9B3B63722E2EA58001CEB9A /* HBQueueItemWorkingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBQueueItemWorkingView.h; sourceTree = "<group>"; };
A9B3B63822E2EA58001CEB9A /* HBQueueItemWorkingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBQueueItemWorkingView.m; sourceTree = "<group>"; };
+ A9B5568622FFE5370050D582 /* HBOutputRedirect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HBOutputRedirect.h; sourceTree = "<group>"; };
A9B6B9ED217B38D200B957AE /* HBLocalizationUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBLocalizationUtilities.h; sourceTree = "<group>"; };
A9B6B9F0217B408E00B957AE /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
A9B6B9F3217B408E00B957AE /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -834,6 +861,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ A964D39222FDE8EE00DFCAEA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A990C55322FF4FBA00E07CE2 /* HandBrakeKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
A9736EFE1C7DA5FE008F1D18 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -942,6 +977,7 @@
273F200214ADAE950021BE6D /* HandBrakeCLI */,
A9736F031C7DA5FE008F1D18 /* HandBrakeKit */,
A9736F111C7DA5FE008F1D18 /* HandBrakeKitTests */,
+ A964D39622FDE8EE00DFCAEA /* HandBrakeXPCService */,
273F200014ADAE950021BE6D /* Products */,
27D6C72314B1013400B785E4 /* Products (external) */,
273F20CD14ADC8E60021BE6D /* Resources */,
@@ -958,6 +994,7 @@
273F203914ADBC210021BE6D /* HandBrake.app */,
A9736F021C7DA5FE008F1D18 /* HandBrakeKit.framework */,
A9736F0B1C7DA5FE008F1D18 /* HandBrakeKitTests.xctest */,
+ A964D39522FDE8EE00DFCAEA /* HandBrakeXPCService.xpc */,
);
name = Products;
sourceTree = "<group>";
@@ -1187,6 +1224,8 @@
children = (
A9706CB21AC1436F00BAEAA8 /* HBApplication.h */,
A9706CB31AC1436F00BAEAA8 /* HBApplication.m */,
+ A964D3A622FDE91A00DFCAEA /* HBRemoteCore.h */,
+ A964D3A722FDE91B00DFCAEA /* HBRemoteCore.m */,
A95BA15F220CA5DB00A2F9F9 /* HBDistributedArray.h */,
A95BA160220CA5DB00A2F9F9 /* HBDistributedArray.m */,
A9706CB51AC1437800BAEAA8 /* HBExceptionAlertController.h */,
@@ -1282,6 +1321,19 @@
name = "UI Bindings Additions";
sourceTree = "<group>";
};
+ A964D39622FDE8EE00DFCAEA /* HandBrakeXPCService */ = {
+ isa = PBXGroup;
+ children = (
+ A990C55222FF4EBA00E07CE2 /* HandBrakeXPCService.entitlements */,
+ A964D39722FDE8EE00DFCAEA /* HBRemoteCoreProtocol.h */,
+ A964D39822FDE8EE00DFCAEA /* HandBrakeXPCService.h */,
+ A964D39922FDE8EE00DFCAEA /* HandBrakeXPCService.m */,
+ A964D39B22FDE8EE00DFCAEA /* main.m */,
+ A964D39D22FDE8EE00DFCAEA /* Info.plist */,
+ );
+ path = HandBrakeXPCService;
+ sourceTree = "<group>";
+ };
A9736F031C7DA5FE008F1D18 /* HandBrakeKit */ = {
isa = PBXGroup;
children = (
@@ -1344,7 +1396,9 @@
A98F00771A972007001C2298 /* Output Redirect */ = {
isa = PBXGroup;
children = (
- 273F209D14ADBE670021BE6D /* HBOutputRedirect.h */,
+ A954010122FF397000F83A5F /* HBRedirect.h */,
+ A954010222FF397000F83A5F /* HBRedirect.m */,
+ A9B5568622FFE5370050D582 /* HBOutputRedirect.h */,
273F209E14ADBE670021BE6D /* HBOutputRedirect.m */,
A91AFD0A1A948827009BECED /* HBOutputFileWriter.h */,
A91AFD0B1A948827009BECED /* HBOutputFileWriter.m */,
@@ -1530,9 +1584,9 @@
A91F97351D7B2A4E00D82DCE /* HBAudioTransformers.h in Headers */,
A98B8E241C7DD2A200B810C9 /* HBPresetCoding.h in Headers */,
A9294CC91DC4BBF7004D3415 /* HBJob+Private.h in Headers */,
+ A91D54871E378ABD006D0997 /* HBSecurityAccessToken.h in Headers */,
A91CE2FE1C7DB99D0068F46F /* HBTreeNode.h in Headers */,
A9B6B9EE217B38D200B957AE /* HBLocalizationUtilities.h in Headers */,
- A91D54871E378ABD006D0997 /* HBSecurityAccessToken.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1588,12 +1642,30 @@
);
dependencies = (
A91CE2EF1C7DB40D0068F46F /* PBXTargetDependency */,
+ A964D39F22FDE8EE00DFCAEA /* PBXTargetDependency */,
);
name = HandBrake;
productName = HandBrake;
productReference = 273F203914ADBC210021BE6D /* HandBrake.app */;
productType = "com.apple.product-type.application";
};
+ A964D39422FDE8EE00DFCAEA /* HandBrakeXPCService */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A964D3A522FDE8EE00DFCAEA /* Build configuration list for PBXNativeTarget "HandBrakeXPCService" */;
+ buildPhases = (
+ A964D39122FDE8EE00DFCAEA /* Sources */,
+ A964D39222FDE8EE00DFCAEA /* Frameworks */,
+ A964D39322FDE8EE00DFCAEA /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = HandBrakeXPCService;
+ productName = HandBrakeXPCService;
+ productReference = A964D39522FDE8EE00DFCAEA /* HandBrakeXPCService.xpc */;
+ productType = "com.apple.product-type.xpc-service";
+ };
A9736F011C7DA5FE008F1D18 /* HandBrakeKit */ = {
isa = PBXNativeTarget;
buildConfigurationList = A9736F1D1C7DA5FE008F1D18 /* Build configuration list for PBXNativeTarget "HandBrakeKit" */;
@@ -1656,6 +1728,9 @@
};
};
};
+ A964D39422FDE8EE00DFCAEA = {
+ CreatedOnToolsVersion = 10.3;
+ };
A96A4F7C217A4C2B00755E35 = {
CreatedOnToolsVersion = 10.1;
ProvisioningStyle = Automatic;
@@ -1691,6 +1766,7 @@
A9736F011C7DA5FE008F1D18 /* HandBrakeKit */,
A9736F0A1C7DA5FE008F1D18 /* HandBrakeKitTests */,
273F203814ADBC200021BE6D /* HandBrake */,
+ A964D39422FDE8EE00DFCAEA /* HandBrakeXPCService */,
);
};
/* End PBXProject section */
@@ -1745,6 +1821,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ A964D39322FDE8EE00DFCAEA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
A9736F001C7DA5FE008F1D18 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1802,6 +1885,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ A954010322FF397000F83A5F /* HBRedirect.m in Sources */,
A95BA161220CA5DB00A2F9F9 /* HBDistributedArray.m in Sources */,
A916C99B1C844A0800C7B560 /* HBTableView.m in Sources */,
A916C9991C8449E200C7B560 /* main.mm in Sources */,
@@ -1846,6 +1930,7 @@
A9C61F9E22E31CDB00C28E7C /* HBFlippedClipView.m in Sources */,
273F20B414ADBE670021BE6D /* HBOutputRedirect.m in Sources */,
A95BA15D220C968500A2F9F9 /* HBQueueItem.m in Sources */,
+ A964D3A822FDE91B00DFCAEA /* HBRemoteCore.m in Sources */,
A9D0FA771C1C284D0003F2A9 /* HBFocusRingView.m in Sources */,
A91AFD0C1A948827009BECED /* HBOutputFileWriter.m in Sources */,
A9D363512209C08600D8EFEA /* HBQueueItemView.m in Sources */,
@@ -1864,6 +1949,17 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ A964D39122FDE8EE00DFCAEA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A954010022FF240E00F83A5F /* HBOutputRedirect.m in Sources */,
+ A964D39C22FDE8EE00DFCAEA /* main.m in Sources */,
+ A964D39A22FDE8EE00DFCAEA /* HandBrakeXPCService.m in Sources */,
+ A9B5568522FFE4870050D582 /* HBRedirect.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
A9736EFD1C7DA5FE008F1D18 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1928,6 +2024,11 @@
target = 273F203814ADBC200021BE6D /* HandBrake */;
targetProxy = A91CE2FF1C7DBA2C0068F46F /* PBXContainerItemProxy */;
};
+ A964D39F22FDE8EE00DFCAEA /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A964D39422FDE8EE00DFCAEA /* HandBrakeXPCService */;
+ targetProxy = A964D39E22FDE8EE00DFCAEA /* PBXContainerItemProxy */;
+ };
A96A4F86217A4C8900755E35 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = A96A4F7C217A4C2B00755E35 /* FakeTarget */;
@@ -2503,6 +2604,7 @@
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
+ CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -2534,6 +2636,7 @@
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = "";
+ CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -2575,6 +2678,254 @@
};
name = release;
};
+ A964D3A122FDE8EE00DFCAEA /* debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEVELOPMENT_TEAM = "";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = HandBrakeXPCService/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../Frameworks";
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = fr.handbrake.HandBrakeXPCService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ };
+ name = debug;
+ };
+ A964D3A222FDE8EE00DFCAEA /* debug-sandbox */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = HandBrakeXPCService/HandBrakeXPCService.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DEVELOPMENT_TEAM = "";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = HandBrakeXPCService/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../Frameworks";
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = fr.handbrake.HandBrakeXPCService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ };
+ name = "debug-sandbox";
+ };
+ A964D3A322FDE8EE00DFCAEA /* release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = "";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = HandBrakeXPCService/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../Frameworks";
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = fr.handbrake.HandBrakeXPCService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ };
+ name = release;
+ };
+ A964D3A422FDE8EE00DFCAEA /* release-sandbox */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = HandBrakeXPCService/HandBrakeXPCService.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = "";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = HandBrakeXPCService/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../Frameworks";
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = fr.handbrake.HandBrakeXPCService;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ };
+ name = "release-sandbox";
+ };
A96A4F7D217A4C2B00755E35 /* debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -3372,6 +3723,17 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = release;
};
+ A964D3A522FDE8EE00DFCAEA /* Build configuration list for PBXNativeTarget "HandBrakeXPCService" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A964D3A122FDE8EE00DFCAEA /* debug */,
+ A964D3A222FDE8EE00DFCAEA /* debug-sandbox */,
+ A964D3A322FDE8EE00DFCAEA /* release */,
+ A964D3A422FDE8EE00DFCAEA /* release-sandbox */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = release;
+ };
A96A4F81217A4C2B00755E35 /* Build configuration list for PBXAggregateTarget "FakeTarget" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake-Release-Sandbox.xcscheme b/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake-Release-Sandbox.xcscheme
index 1e04e9b67..cd9811d6a 100644
--- a/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake-Release-Sandbox.xcscheme
+++ b/macosx/HandBrake.xcodeproj/xcshareddata/xcschemes/HandBrake-Release-Sandbox.xcscheme
@@ -83,7 +83,6 @@
buildConfiguration = "release-sandbox"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- disableMainThreadChecker = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/macosx/HandBrakeKit/HandBrakeKit.h b/macosx/HandBrakeKit/HandBrakeKit.h
index 3e388855c..3aed96db5 100644
--- a/macosx/HandBrakeKit/HandBrakeKit.h
+++ b/macosx/HandBrakeKit/HandBrakeKit.h
@@ -51,3 +51,4 @@ FOUNDATION_EXPORT const unsigned char HandBrakeKitVersionString[];
#import <HandBrakeKit/HBFilters+UIAdditions.h>
#import <HandBrakeKit/HBAudioTransformers.h>
+#import <HandBrakeKit/HBSecurityAccessToken.h>
diff --git a/macosx/HandBrakeXPCService/HBRemoteCoreProtocol.h b/macosx/HandBrakeXPCService/HBRemoteCoreProtocol.h
new file mode 100644
index 000000000..5fd0805e0
--- /dev/null
+++ b/macosx/HandBrakeXPCService/HBRemoteCoreProtocol.h
@@ -0,0 +1,41 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Foundation/Foundation.h>
+
+@import HandBrakeKit;
+
+@protocol HBRemoteCoreProtocol
+
+- (void)setUpWithLogLevel:(NSInteger)level name:(NSString *)name;
+- (void)tearDown;
+
+- (void)provideResourceAccessWithBookmarks:(NSArray<NSData *> *)bookmarks;
+
+- (void)setAutomaticallyPreventSleep:(BOOL)automaticallyPreventSleep;
+
+- (void)preventSleep;
+- (void)allowSleep;
+
+- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds withReply:(void (^)(HBCoreResult))reply;
+- (void)cancelScan;
+
+- (void)encodeJob:(HBJob *)job withReply:(void (^)(HBCoreResult))reply;
+- (void)cancelEncode;
+
+- (void)pauseEncode;
+- (void)resumeEncode;
+
+@end
+
+@protocol HBRemoteProgressProtocol
+
+- (void)updateState:(HBState)state;
+- (void)updateProgress:(double)currentProgress hours:(int)hours minutes:(int)minutes seconds:(int)seconds state:(HBState)state info:(NSString *)info;
+
+- (void)forwardOutput:(NSString *)text;
+- (void)forwardError:(NSString *)text;
+
+@end
+
diff --git a/macosx/HandBrakeXPCService/HandBrakeXPCService.entitlements b/macosx/HandBrakeXPCService/HandBrakeXPCService.entitlements
new file mode 100644
index 000000000..6431476ba
--- /dev/null
+++ b/macosx/HandBrakeXPCService/HandBrakeXPCService.entitlements
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.app-sandbox</key>
+ <true/>
+ <key>com.apple.security.temporary-exception.apple-events</key>
+ <array>
+ <string>com.apple.systemevents</string>
+ </array>
+ <key>com.apple.security.temporary-exception.files.absolute-path.read-only</key>
+ <array>
+ <string>/usr/local/</string>
+ </array>
+ <key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
+ <array>
+ <string>/.dvdcss/</string>
+ </array>
+</dict>
+</plist>
diff --git a/macosx/HandBrakeXPCService/HandBrakeXPCService.h b/macosx/HandBrakeXPCService/HandBrakeXPCService.h
new file mode 100644
index 000000000..d7a084bd0
--- /dev/null
+++ b/macosx/HandBrakeXPCService/HandBrakeXPCService.h
@@ -0,0 +1,13 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Foundation/Foundation.h>
+#import "HBRemoteCoreProtocol.h"
+
+@interface HandBrakeXPCService : NSObject <HBRemoteCoreProtocol>
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithConnection:(NSXPCConnection *)connection;
+
+@end
diff --git a/macosx/HandBrakeXPCService/HandBrakeXPCService.m b/macosx/HandBrakeXPCService/HandBrakeXPCService.m
new file mode 100644
index 000000000..ffd910b55
--- /dev/null
+++ b/macosx/HandBrakeXPCService/HandBrakeXPCService.m
@@ -0,0 +1,193 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import "HandBrakeXPCService.h"
+#import "HBOutputRedirect.h"
+
+@import HandBrakeKit;
+
+static void *HandBrakeXPCServiceContext = &HandBrakeXPCServiceContext;
+
+@interface HandBrakeXPCService () <HBOutputRedirectListening>
+
+@property (nonatomic, readonly) HBCore *core;
+
+@property (nonatomic, readonly, copy) HBCoreProgressHandler progressHandler;
+@property (nonatomic, readonly, copy) HBCoreCompletionHandler completionHandler;
+@property (nonatomic, readwrite, copy) void (^reply)(HBCoreResult);
+
+@property (nonatomic, readonly, weak) NSXPCConnection *connection;
+@property (nonatomic, readonly) dispatch_queue_t queue;
+
+@property (nonatomic, readwrite) NSArray<NSURL *> *urls;
+
+@end
+
+@implementation HandBrakeXPCService
+
+- (instancetype)initWithConnection:(NSXPCConnection *)connection
+{
+ self = [super init];
+ if (self)
+ {
+ _connection = connection;
+
+ dispatch_queue_attr_t attr;
+ attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0);
+ _queue = dispatch_queue_create("fr.handbrake.CoreQueue", attr);
+
+ // Add ourself as stderr/stdout listener
+ [HBOutputRedirect.stderrRedirect addListener:self queue:_queue];
+ [HBOutputRedirect.stdoutRedirect addListener:self queue:_queue];
+ }
+ return self;
+}
+
+- (void)setUpWithLogLevel:(NSInteger)level name:(NSString *)name
+{
+ [HBCore initGlobal];
+
+ _core = [[HBCore alloc] initWithLogLevel:level queue:_queue];
+ _core.name = name;
+
+ // Completion handler
+ void (^completionHandler)(HBCoreResult result) = ^(HBCoreResult result)
+ {
+ self->_progressHandler = nil;
+ self.reply(result);
+ self.reply = nil;
+ };
+ _completionHandler = completionHandler;
+
+ // Set up observers
+ [self.core addObserver:self forKeyPath:@"state"
+ options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
+ context:HandBrakeXPCServiceContext];
+}
+
+- (void)tearDown
+{
+ _core = nil;
+ [HBCore closeGlobal];
+}
+
+- (void)provideResourceAccessWithBookmarks:(NSArray<NSData *> *)bookmarks
+{
+ dispatch_sync(_queue, ^{
+ for (NSData *bookmark in bookmarks)
+ {
+ NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark options:0 relativeToURL:nil bookmarkDataIsStale:NULL error:NULL];
+ self.urls = @[url];
+ }
+ });
+}
+
+- (void)setAutomaticallyPreventSleep:(BOOL)automaticallyPreventSleep
+{
+ dispatch_sync(_queue, ^{
+ self.core.automaticallyPreventSleep = automaticallyPreventSleep;
+ });
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ if (context == HandBrakeXPCServiceContext)
+ {
+ [self.connection.remoteObjectProxy updateState:self.core.state];
+ }
+ else
+ {
+ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+ }
+}
+
+- (void)preventSleep
+{
+ dispatch_sync(_queue, ^{
+ [self.core preventSleep];
+ });
+}
+
+- (void)allowSleep
+{
+ dispatch_sync(_queue, ^{
+ [self.core allowSleep];
+ });
+}
+
+- (void)scanURL:(NSURL *)url titleIndex:(NSUInteger)index previews:(NSUInteger)previewsNum minDuration:(NSUInteger)seconds withReply:(void (^)(HBCoreResult))reply
+{
+ dispatch_sync(_queue, ^{
+ void (^progressHandler)(HBState state, HBProgress progress, NSString *info) = ^(HBState state, HBProgress progress, NSString *info)
+ {
+ [self.connection.remoteObjectProxy updateProgress:progress.percent hours:progress.hours minutes:progress.minutes seconds:progress.seconds state:state info:info];
+ };
+ self->_progressHandler = progressHandler;
+ self.reply = reply;
+
+ [self.core scanURL:url titleIndex:index previews:previewsNum minDuration:seconds
+ progressHandler:self.progressHandler
+ completionHandler:self.completionHandler];
+ });
+}
+
+- (void)cancelScan
+{
+ dispatch_sync(_queue, ^{
+ [self.core cancelScan];
+ });
+}
+
+ - (void)encodeJob:(HBJob *)job withReply:(void (^)(HBCoreResult))reply;
+{
+ dispatch_sync(_queue, ^{
+ void (^progressHandler)(HBState state, HBProgress progress, NSString *info) = ^(HBState state, HBProgress progress, NSString *info)
+ {
+ [self.connection.remoteObjectProxy updateProgress:progress.percent hours:progress.hours minutes:progress.minutes seconds:progress.seconds state:state info:info];
+ };
+ self->_progressHandler = progressHandler;
+ self.reply = reply;
+
+ // Reset the title in the job.
+ job.title = self.core.titles.firstObject;
+ [self.core encodeJob:job
+ progressHandler:self.progressHandler
+ completionHandler:self.completionHandler];
+ });
+}
+
+- (void)cancelEncode
+{
+ dispatch_sync(_queue, ^{
+ [self.core cancelEncode];
+ });
+}
+
+- (void)pauseEncode
+{
+ dispatch_sync(_queue, ^{
+ [self.core pause];
+ });
+}
+
+- (void)resumeEncode
+{
+ dispatch_sync(_queue, ^{
+ [self.core resume];
+ });
+}
+
+- (void)redirect:(nonnull NSString *)text type:(HBRedirectType)type
+{
+ if (type == HBRedirectTypeOutput)
+ {
+ [self.connection.remoteObjectProxy forwardError:text];
+ }
+ else
+ {
+ [self.connection.remoteObjectProxy forwardOutput:text];
+ }
+}
+
+@end
diff --git a/macosx/HandBrakeXPCService/Info.plist b/macosx/HandBrakeXPCService/Info.plist
new file mode 100644
index 000000000..78928db23
--- /dev/null
+++ b/macosx/HandBrakeXPCService/Info.plist
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleDisplayName</key>
+ <string>HandBrakeXPCService</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>XPC!</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>XPCService</key>
+ <dict>
+ <key>ServiceType</key>
+ <string>Application</string>
+ </dict>
+</dict>
+</plist>
diff --git a/macosx/HandBrakeXPCService/main.m b/macosx/HandBrakeXPCService/main.m
new file mode 100644
index 000000000..e127c9a5b
--- /dev/null
+++ b/macosx/HandBrakeXPCService/main.m
@@ -0,0 +1,38 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#import <Foundation/Foundation.h>
+#import "HandBrakeXPCService.h"
+
+@interface HBXPCServiceDelegate : NSObject <NSXPCListenerDelegate>
+@end
+
+@implementation HBXPCServiceDelegate
+
+- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
+{
+ newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(HBRemoteCoreProtocol)];
+ newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(HBRemoteProgressProtocol)];
+
+ HandBrakeXPCService *exportedObject = [[HandBrakeXPCService alloc] initWithConnection:newConnection];
+ newConnection.exportedObject = exportedObject;
+
+ [newConnection resume];
+
+ return YES;
+}
+
+@end
+
+int main(int argc, const char *argv[])
+{
+ HBXPCServiceDelegate *delegate = [HBXPCServiceDelegate new];
+
+ NSXPCListener *listener = [NSXPCListener serviceListener];
+ listener.delegate = delegate;
+
+ [listener resume];
+
+ return 0;
+}