Commit db62975c authored by Felix Paul Kühne's avatar Felix Paul Kühne

macosx: split main interface class

parent 6916c8d1
......@@ -1240,6 +1240,9 @@
7D3F652718805297005776C4 /* BWQuincyManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BWQuincyManager.m; path = ../../../modules/gui/macosx/BWQuincyManager.m; sourceTree = SOURCE_ROOT; };
7D3F652818805297005776C4 /* BWQuincyUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BWQuincyUI.h; path = ../../../modules/gui/macosx/BWQuincyUI.h; sourceTree = SOURCE_ROOT; };
7D3F652918805297005776C4 /* BWQuincyUI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BWQuincyUI.m; path = ../../../modules/gui/macosx/BWQuincyUI.m; sourceTree = SOURCE_ROOT; };
7D871D371B5E6844000B56C0 /* intf-prefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "intf-prefs.h"; path = "../../../modules/gui/macosx/intf-prefs.h"; sourceTree = "<group>"; };
7D871D381B5E6844000B56C0 /* intf-prefs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "intf-prefs.m"; path = "../../../modules/gui/macosx/intf-prefs.m"; sourceTree = "<group>"; };
7D871D391B5E684D000B56C0 /* helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = helpers.h; path = ../../../modules/gui/macosx/helpers.h; sourceTree = "<group>"; };
7D8BB0B318302AC000FAE9B7 /* DebugMessageVisualizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DebugMessageVisualizer.h; path = ../../../modules/gui/macosx/DebugMessageVisualizer.h; sourceTree = SOURCE_ROOT; };
7D8BB0B418302AC000FAE9B7 /* DebugMessageVisualizer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = DebugMessageVisualizer.m; path = ../../../modules/gui/macosx/DebugMessageVisualizer.m; sourceTree = SOURCE_ROOT; };
7D8BB0B61830311300FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/DebugMessageVisualizer.xib; sourceTree = "<group>"; };
......@@ -1810,6 +1813,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
7D871D391B5E684D000B56C0 /* helpers.h */,
8EE1AF9F044465080059A3A7 /* about.h */,
8EE1AFA0044465080059A3A7 /* about.m */,
7DF0435E1972E26A0022B534 /* AddonListDataSource.h */,
......@@ -1845,6 +1849,8 @@
2AEF857709A5FEC900130822 /* fspanel.m */,
8ED6C27C03E2EB1C0059A3A7 /* intf.h */,
8ED6C27D03E2EB1C0059A3A7 /* intf.m */,
7D871D371B5E6844000B56C0 /* intf-prefs.h */,
7D871D381B5E6844000B56C0 /* intf-prefs.m */,
7DF812ED1B555A340052293C /* InputManager.h */,
7DF812EE1B555A340052293C /* InputManager.m */,
7DF812EF1B555C8E0052293C /* KeyboardBacklight.h */,
......
......@@ -80,30 +80,34 @@ const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
- (id)init
{
_openInExclusiveMode = YES;
queue = NULL;
hidDeviceInterface = NULL;
NSMutableDictionary * mutableCookieToButtonMapping = [[NSMutableDictionary alloc] init];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"33_31_30_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Minus] forKey:@"33_32_30_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"33_22_21_20_2_33_22_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"33_23_21_20_2_33_23_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"33_24_21_20_2_33_24_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"33_25_21_20_2_33_25_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"33_21_20_14_12_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"33_21_20_13_12_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"33_21_20_2_33_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"37_33_21_20_2_37_33_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonFullscreen] forKey:@"33_21_20_3_2_33_21_20_3_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"42_33_23_21_20_2_33_23_21_20_2_"];
_cookieToButtonMapping = [[NSDictionary alloc] initWithDictionary: mutableCookieToButtonMapping];
/* defaults */
_simulatesPlusMinusHold = YES;
_maximumClickCountTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE;
self = [super init];
if (self) {
_openInExclusiveMode = YES;
queue = NULL;
hidDeviceInterface = NULL;
NSMutableDictionary * mutableCookieToButtonMapping = [[NSMutableDictionary alloc] init];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"33_31_30_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Minus] forKey:@"33_32_30_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"33_22_21_20_2_33_22_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"33_23_21_20_2_33_23_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"33_24_21_20_2_33_24_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"33_25_21_20_2_33_25_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"33_21_20_14_12_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"33_21_20_13_12_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"33_21_20_2_33_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"37_33_21_20_2_37_33_21_20_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonPlay] forKey:@"33_21_20_8_2_33_21_20_8_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:k2009RemoteButtonFullscreen] forKey:@"33_21_20_3_2_33_21_20_3_2_"];
[mutableCookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"42_33_23_21_20_2_33_23_21_20_2_"];
_cookieToButtonMapping = [[NSDictionary alloc] initWithDictionary: mutableCookieToButtonMapping];
/* defaults */
_simulatesPlusMinusHold = YES;
_maximumClickCountTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE;
}
return self;
}
- (void) dealloc {
......
......@@ -27,6 +27,7 @@
#import "CoreInteraction.h"
#import "MainMenu.h"
#import "fspanel.h"
#import "playlist.h"
#import "CompatibilityFixes.h"
/*****************************************************************************
......@@ -632,7 +633,7 @@ frame.origin.x = f_width + frame.origin.x; \
if (!config_GetInt(VLCIntf, "macosx-show-effects-button"))
[self removeEffectsButton:YES];
[[VLCMain sharedInstance] playbackModeUpdated];
[[[VLCMain sharedInstance] playlist] playbackModeUpdated];
}
......
/*****************************************************************************
* CoreInteraction.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2014 Felix Paul Kühne
* Copyright (C) 2011-2015 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -66,6 +66,8 @@
- (void)volumeUp;
- (void)volumeDown;
- (void)toggleMute;
- (void)startListeningWithAppleRemote;
- (void)stopListeningWithAppleRemote;
- (void)addSubtitlesToCurrentInput:(NSArray *)paths;
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
......@@ -80,4 +82,7 @@
- (void)setVideoFilterProperty: (const char *)psz_name forFilter: (const char *)psz_filter string: (const char *)psz_value;
- (void)setVideoFilterProperty: (const char *)psz_name forFilter: (const char *)psz_filter boolean: (BOOL)b_value;
- (void)updateCurrentlyUsedHotkeys;
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force;
@end
/*****************************************************************************
* CoreInteraction.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2011-2014 Felix Paul Kühne
* Copyright (C) 2011-2015 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
......@@ -36,6 +36,24 @@
#import <vlc_url.h>
#import <vlc_modules.h>
#import <vlc_charset.h>
#include <vlc_plugin.h>
#import "SPMediaKeyTap.h"
#import "AppleRemote.h"
#import "InputManager.h"
#import "controls.h"
static int BossCallback(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
dispatch_async(dispatch_get_main_queue(), ^{
[[VLCCoreInteraction sharedInstance] pause];
[[NSApplication sharedApplication] hide:nil];
});
return VLC_SUCCESS;
}
}
@interface VLCCoreInteraction ()
{
......@@ -43,6 +61,17 @@
mtime_t timeA, timeB;
float f_maxVolume;
/* media key support */
BOOL b_mediaKeySupport;
BOOL b_mediakeyJustJumped;
SPMediaKeyTap *_mediaKeyController;
BOOL b_mediaKeyTrapEnabled;
AppleRemote *_remote;
BOOL b_remote_button_hold; /* true as long as the user holds the left,right,plus or minus on the remote control */
NSArray *_usedHotkeys;
}
@end
......@@ -62,8 +91,36 @@
return sharedInstance;
}
- (instancetype)init
{
self = [super init];
if (self) {
intf_thread_t *p_intf = VLCIntf;
/* init media key support */
b_mediaKeySupport = var_InheritBool(p_intf, "macosx-mediakeys");
if (b_mediaKeySupport) {
_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
[SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey,
nil]];
}
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(coreChangedMediaKeySupportSetting:) name: @"VLCMediaKeySupportSettingChanged" object: nil];
/* init Apple Remote support */
_remote = [[AppleRemote alloc] init];
[_remote setClickCountEnabledButtons: kRemoteButtonPlay];
[_remote setDelegate: self];
var_AddCallback(p_intf->p_libvlc, "intf-boss", BossCallback, (__bridge void *)self);
}
return self;
}
- (void)dealloc
{
intf_thread_t *p_intf = VLCIntf;
var_DelCallback(p_intf->p_libvlc, "intf-boss", BossCallback, (__bridge void *)self);
[[NSNotificationCenter defaultCenter] removeObserver: self];
}
......@@ -913,4 +970,309 @@
}
}
#pragma mark -
#pragma mark Media Key support
- (void)resetMediaKeyJump
{
b_mediakeyJustJumped = NO;
}
- (void)coreChangedMediaKeySupportSetting: (NSNotification *)o_notification
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return;
b_mediaKeySupport = var_InheritBool(p_intf, "macosx-mediakeys");
if (b_mediaKeySupport && !_mediaKeyController)
_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
VLCMain *main = [VLCMain sharedInstance];
if (b_mediaKeySupport && ([[[main playlist] model] hasChildren] ||
[[main inputManager] hasInput])) {
if (!b_mediaKeyTrapEnabled) {
b_mediaKeyTrapEnabled = YES;
msg_Dbg(p_intf, "Enable media key support");
[_mediaKeyController startWatchingMediaKeys];
}
} else {
if (b_mediaKeyTrapEnabled) {
b_mediaKeyTrapEnabled = NO;
msg_Dbg(p_intf, "Disable media key support");
[_mediaKeyController stopWatchingMediaKeys];
}
}
}
-(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event
{
if (b_mediaKeySupport) {
assert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys);
int keyCode = (([event data1] & 0xFFFF0000) >> 16);
int keyFlags = ([event data1] & 0x0000FFFF);
int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA;
int keyRepeat = (keyFlags & 0x1);
if (keyCode == NX_KEYTYPE_PLAY && keyState == 0)
[self playOrPause];
if ((keyCode == NX_KEYTYPE_FAST || keyCode == NX_KEYTYPE_NEXT) && !b_mediakeyJustJumped) {
if (keyState == 0 && keyRepeat == 0)
[self next];
else if (keyRepeat == 1) {
[self forwardShort];
b_mediakeyJustJumped = YES;
[self performSelector:@selector(resetMediaKeyJump)
withObject: NULL
afterDelay:0.25];
}
}
if ((keyCode == NX_KEYTYPE_REWIND || keyCode == NX_KEYTYPE_PREVIOUS) && !b_mediakeyJustJumped) {
if (keyState == 0 && keyRepeat == 0)
[self previous];
else if (keyRepeat == 1) {
[self backwardShort];
b_mediakeyJustJumped = YES;
[self performSelector:@selector(resetMediaKeyJump)
withObject: NULL
afterDelay:0.25];
}
}
}
}
#pragma mark -
#pragma mark Apple Remote Control
- (void)startListeningWithAppleRemote
{
[_remote startListening: self];
}
- (void)stopListeningWithAppleRemote
{
[_remote stopListening:self];
}
/* Helper method for the remote control interface in order to trigger forward/backward and volume
increase/decrease as long as the user holds the left/right, plus/minus button */
- (void) executeHoldActionForRemoteButton: (NSNumber*) buttonIdentifierNumber
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return;
if (b_remote_button_hold) {
switch([buttonIdentifierNumber intValue]) {
case kRemoteButtonRight_Hold:
[self forward];
break;
case kRemoteButtonLeft_Hold:
[self backward];
break;
case kRemoteButtonVolume_Plus_Hold:
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_UP);
break;
case kRemoteButtonVolume_Minus_Hold:
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_DOWN);
break;
}
if (b_remote_button_hold) {
/* trigger event */
[self performSelector:@selector(executeHoldActionForRemoteButton:)
withObject:buttonIdentifierNumber
afterDelay:0.25];
}
}
}
/* Apple Remote callback */
- (void) appleRemoteButton: (AppleRemoteEventIdentifier)buttonIdentifier
pressedDown: (BOOL) pressedDown
clickCount: (unsigned int) count
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return;
switch(buttonIdentifier) {
case k2009RemoteButtonFullscreen:
[self toggleFullscreen];
break;
case k2009RemoteButtonPlay:
[self playOrPause];
break;
case kRemoteButtonPlay:
if (count >= 2)
[self toggleFullscreen];
else
[self playOrPause];
break;
case kRemoteButtonVolume_Plus:
if (config_GetInt(VLCIntf, "macosx-appleremote-sysvol"))
[NSSound increaseSystemVolume];
else
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_UP);
break;
case kRemoteButtonVolume_Minus:
if (config_GetInt(VLCIntf, "macosx-appleremote-sysvol"))
[NSSound decreaseSystemVolume];
else
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_DOWN);
break;
case kRemoteButtonRight:
if (config_GetInt(VLCIntf, "macosx-appleremote-prevnext"))
[self forward];
else
[self next];
break;
case kRemoteButtonLeft:
if (config_GetInt(VLCIntf, "macosx-appleremote-prevnext"))
[self backward];
else
[self previous];
break;
case kRemoteButtonRight_Hold:
case kRemoteButtonLeft_Hold:
case kRemoteButtonVolume_Plus_Hold:
case kRemoteButtonVolume_Minus_Hold:
/* simulate an event as long as the user holds the button */
b_remote_button_hold = pressedDown;
if (pressedDown) {
NSNumber* buttonIdentifierNumber = [NSNumber numberWithInt:buttonIdentifier];
[self performSelector:@selector(executeHoldActionForRemoteButton:)
withObject:buttonIdentifierNumber];
}
break;
case kRemoteButtonMenu:
[[[VLCMain sharedInstance] controls] showPosition: self]; //FIXME
break;
case kRemoteButtonPlay_Sleep:
{
NSAppleScript * script = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to sleep"];
[script executeAndReturnError:nil];
break;
}
default:
/* Add here whatever you want other buttons to do */
break;
}
}
#pragma mark -
#pragma mark Key Shortcuts
/*****************************************************************************
* hasDefinedShortcutKey: Check to see if the key press is a defined VLC
* shortcut key. If it is, pass it off to VLC for handling and return YES,
* otherwise ignore it and return NO (where it will get handled by Cocoa).
*****************************************************************************/
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return NO;
unichar key = 0;
vlc_value_t val;
unsigned int i_pressed_modifiers = 0;
val.i_int = 0;
i_pressed_modifiers = [o_event modifierFlags];
if (i_pressed_modifiers & NSControlKeyMask)
val.i_int |= KEY_MODIFIER_CTRL;
if (i_pressed_modifiers & NSAlternateKeyMask)
val.i_int |= KEY_MODIFIER_ALT;
if (i_pressed_modifiers & NSShiftKeyMask)
val.i_int |= KEY_MODIFIER_SHIFT;
if (i_pressed_modifiers & NSCommandKeyMask)
val.i_int |= KEY_MODIFIER_COMMAND;
NSString * characters = [o_event charactersIgnoringModifiers];
if ([characters length] > 0) {
key = [[characters lowercaseString] characterAtIndex: 0];
/* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
if (key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask) {
[self toggleFullscreen];
return YES;
}
if (!b_force) {
switch(key) {
case NSDeleteCharacter:
case NSDeleteFunctionKey:
case NSDeleteCharFunctionKey:
case NSBackspaceCharacter:
case NSUpArrowFunctionKey:
case NSDownArrowFunctionKey:
case NSEnterCharacter:
case NSCarriageReturnCharacter:
return NO;
}
}
val.i_int |= CocoaKeyToVLC(key);
BOOL b_found_key = NO;
for (NSUInteger i = 0; i < [_usedHotkeys count]; i++) {
NSString *str = [_usedHotkeys objectAtIndex:i];
unsigned int i_keyModifiers = [[VLCStringUtility sharedInstance] VLCModifiersToCocoa: str];
if ([[characters lowercaseString] isEqualToString: [[VLCStringUtility sharedInstance] VLCKeyToString: str]] &&
(i_keyModifiers & NSShiftKeyMask) == (i_pressed_modifiers & NSShiftKeyMask) &&
(i_keyModifiers & NSControlKeyMask) == (i_pressed_modifiers & NSControlKeyMask) &&
(i_keyModifiers & NSAlternateKeyMask) == (i_pressed_modifiers & NSAlternateKeyMask) &&
(i_keyModifiers & NSCommandKeyMask) == (i_pressed_modifiers & NSCommandKeyMask)) {
b_found_key = YES;
break;
}
}
if (b_found_key) {
var_SetInteger(p_intf->p_libvlc, "key-pressed", val.i_int);
return YES;
}
}
return NO;
}
- (void)updateCurrentlyUsedHotkeys
{
NSMutableArray *mutArray = [[NSMutableArray alloc] init];
/* Get the main Module */
module_t *p_main = module_get_main();
assert(p_main);
unsigned confsize;
module_config_t *p_config;
p_config = module_config_get (p_main, &confsize);
for (size_t i = 0; i < confsize; i++) {
module_config_t *p_item = p_config + i;
if (CONFIG_ITEM(p_item->i_type) && p_item->psz_name != NULL
&& !strncmp(p_item->psz_name , "key-", 4)
&& !EMPTY_STR(p_item->psz_text)) {
if (p_item->value.psz)
[mutArray addObject: [NSString stringWithUTF8String:p_item->value.psz]];
}
}
module_config_free (p_config);
_usedHotkeys = [[NSArray alloc] initWithArray:mutArray copyItems:YES];
}
@end
......@@ -29,7 +29,7 @@
@class VLCMain;
@interface InputManager : NSObject
@interface VLCInputManager : NSObject
- (id)initWithMain:(VLCMain *)o_mainObj;
......
......@@ -41,7 +41,7 @@ static int InputThreadChanged(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
InputManager *inputManager = (__bridge InputManager *)param;
VLCInputManager *inputManager = (__bridge VLCInputManager *)param;
[inputManager performSelectorOnMainThread:@selector(inputThreadChanged) withObject:nil waitUntilDone:NO];
}
......@@ -53,7 +53,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
InputManager *inputManager = (__bridge InputManager *)param;
VLCInputManager *inputManager = (__bridge VLCInputManager *)param;
switch (new_val.i_int) {
case INPUT_EVENT_STATE:
......@@ -131,9 +131,8 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
#pragma mark -
#pragma mark InputManager implementation
@interface InputManager()
@interface VLCInputManager()
{
intf_thread_t *p_intf;
VLCMain *o_main;
input_thread_t *p_current_input;
......@@ -150,13 +149,12 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
}
@end
@implementation InputManager
@implementation VLCInputManager
- (id)initWithMain:(VLCMain *)o_mainObj
{
self = [super init];
if(self) {
p_intf = VLCIntf;
o_main = o_mainObj;
var_AddCallback(pl_Get(VLCIntf), "input-current", InputThreadChanged, (__bridge void *)self);
......@@ -168,6 +166,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
- (void)dealloc
{
intf_thread_t *p_intf = VLCIntf;
if (p_current_input) {
/* continue playback where you left off */
[[o_main playlist] storePlaybackPositionForItem:p_current_input];
......@@ -177,7 +176,8 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
p_current_input = NULL;
}
var_DelCallback(pl_Get(VLCIntf), "input-current", InputThreadChanged, (__bridge void *)self);
if (p_intf)
var_DelCallback(p_intf, "input-current", InputThreadChanged, (__bridge void *)self);
dispatch_release(informInputChangedQueue);
}
......@@ -230,7 +230,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
* The serial queue ensures that changed inputs are propagated in the same order as they arrive.
*/
dispatch_async(informInputChangedQueue, ^{
[[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed];
[[ExtensionsManager getInstance:VLCIntf] inputChanged:p_input_changed];
if (p_input_changed)
vlc_object_release(p_input_changed);
});
......@@ -239,6 +239,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
- (void)playbackStatusUpdated
{
intf_thread_t *p_intf = VLCIntf;
int state = -1;
if (p_current_input) {
state = var_GetInteger(p_current_input, "state");
......@@ -363,6 +364,7 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,
- (void)resumeItunesPlayback:(id)sender
{
intf_thread_t *p_intf = VLCIntf;
if (var_InheritInteger(p_intf, "macosx-control-itunes") > 1) {
if (b_has_itunes_paused) {
iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
......
......@@ -100,7 +100,7 @@ static VLCMainWindow *sharedInstance = nil;
defer:flag];
});
[[VLCMain sharedInstance] updateTogglePlaylistState];
[[[VLCMain sharedInstance] playlist] updateTogglePlaylistState];
return sharedInstance;
}
......@@ -146,7 +146,7 @@ static VLCMainWindow *sharedInstance = nil;
else
b_force = YES;
return [[VLCMain sharedInstance] hasDefinedShortcutKey:o_event force:b_force] ||
return [[VLCCoreInteraction sharedInstance] hasDefinedShortcutKey:o_event force:b_force] ||
[(VLCControls *)[[VLCMain sharedInstance] controls] keyEvent:o_event];
}
......
......@@ -18,6 +18,7 @@ EXTRA_LTLIBRARIES = libmacosx_plugin.la
gui_LTLIBRARIES = $(LTLIBmacosx)
libmacosx_plugin_la_SOURCES = \
helpers.h \
about.h about.m \
AddonListDataSource.h AddonListDataSource.m \
AddonsWindowController.h AddonsWindowController.m \
......@@ -38,6 +39,7 @@ libmacosx_plugin_la_SOURCES = \
ExtensionsManager.h ExtensionsManager.m \
eyetv.h eyetv.m \
fspanel.h fspanel.m \
intf-prefs.h intf-prefs.m \
intf.h intf.m \
InputManager.h InputManager.m \
iTunes.h \
......
......@@ -32,6 +32,10 @@
@interface VLCVoutWindowController : NSObject
+ (VLCVoutWindowController *)sharedInstance;
@property (readonly, atomic) NSLock *lock;
@property (readonly, nonatomic) NSInteger currentStatusWindowLevel;
- (VLCVoutView *)setupVoutForWindow:(vout_window_t *)p_wnd withProposedVideoViewPosition:(NSRect)videoViewPosition;
......
......@@ -22,6 +22,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc_vout_display.h>
#import "CompatibilityFixes.h"
#import "VLCVoutWindowController.h"
#import "intf.h"
......@@ -36,6 +38,162 @@
#import "ResumeDialogController.h"
#import "playlist.h"
static atomic_bool b_intf_starting = ATOMIC_VAR_INIT(false);
static int WindowControl(vout_window_t *, int i_query, va_list);
int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
{
@autoreleasepool {
if (cfg->type != VOUT_WINDOW_TYPE_INVALID
&& cfg->type != VOUT_WINDOW_TYPE_NSOBJECT)
return VLC_EGENERIC;
msg_Dbg(p_wnd, "Opening video window");
if (!atomic_load(&b_intf_starting)) {
msg_Err(p_wnd, "Cannot create vout as Mac OS X interface was not found");
return VLC_EGENERIC;
}
NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
VLCVoutWindowController *voutController = [[VLCMain sharedInstance] voutController];
if (!voutController) {
return VLC_EGENERIC;
}
[voutController.lock lock];
SEL sel = @selector(setupVoutForWindow:withProposedVideoViewPosition:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
[inv setTarget:voutController];
[inv setSelector:sel];
[inv setArgument:&p_wnd atIndex:2]; // starting at 2!
[inv setArgument:&proposedVideoViewPosition atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:YES];
VLCVoutView *videoView = nil;
[inv getReturnValue:&videoView];
// this method is not supposed to fail
assert(videoView != nil);
msg_Dbg(VLCIntf, "returning videoview with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height);
p_wnd->handle.nsobject = (void *)CFBridgingRetain(videoView);
[voutController.lock unlock];
p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT;
p_wnd->control = WindowControl;
return VLC_SUCCESS;
}
}
static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
{
@autoreleasepool {
VLCVoutWindowController *voutController = [[VLCMain sharedInstance] voutController];
if (!voutController) {
return VLC_EGENERIC;
}
[voutController.lock lock];
switch(i_query) {
case VOUT_WINDOW_SET_STATE:
{
unsigned i_state = va_arg(args, unsigned);
if (i_state & VOUT_WINDOW_STATE_BELOW)
{
msg_Dbg(p_wnd, "Ignore change to VOUT_WINDOW_STATE_BELOW");
goto out;
}
NSInteger i_cooca_level = NSNormalWindowLevel;
if (i_state & VOUT_WINDOW_STATE_ABOVE)
i_cooca_level = NSStatusWindowLevel;
SEL sel = @selector(setWindowLevel:forWindow:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
[inv setTarget:voutController];
[inv setSelector:sel];
[inv setArgument:&i_cooca_level atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:NO];
break;
}
case VOUT_WINDOW_SET_SIZE:
{
unsigned int i_width = va_arg(args, unsigned int);
unsigned int i_height = va_arg(args, unsigned int);
NSSize newSize = NSMakeSize(i_width, i_height);
SEL sel = @selector(setNativeVideoSize:forWindow:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
[inv setTarget:voutController];
[inv setSelector:sel];
[inv setArgument:&newSize atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:NO];
break;
}
case VOUT_WINDOW_SET_FULLSCREEN:
{
if (var_InheritBool(VLCIntf, "video-wallpaper")) {
msg_Dbg(p_wnd, "Ignore fullscreen event as video-wallpaper is on");
goto out;
}
int i_full = va_arg(args, int);
BOOL b_animation = YES;
SEL sel = @selector(setFullscreen:forWindow:withAnimation:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[voutController methodSignatureForSelector:sel]];
[inv setTarget:voutController];
[inv setSelector:sel];
[inv setArgument:&i_full atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
[inv setArgument:&b_animation atIndex:4];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:NO];
break;
}
default:
{
msg_Warn(p_wnd, "unsupported control query");
[voutController.lock unlock];
return VLC_EGENERIC;
}
}
out:
[voutController.lock unlock];
return VLC_SUCCESS;
}
}
void WindowClose(vout_window_t *p_wnd)
{
@autoreleasepool {
VLCVoutWindowController *voutController = [[VLCMain sharedInstance] voutController];
if (!voutController) {
return;
}
[voutController.lock lock];
[voutController performSelectorOnMainThread:@selector(removeVoutforDisplay:) withObject:[NSValue valueWithPointer:p_wnd] waitUntilDone:NO];
[voutController.lock unlock];
}
}
@interface VLCVoutWindowController ()
{
NSMutableDictionary *o_vout_dict;
......@@ -53,13 +211,28 @@
@implementation VLCVoutWindowController
+ (VLCVoutWindowController *)sharedInstance
{
static VLCVoutWindowController *sharedInstance = nil;
static dispatch_once_t pred;
dispatch_once(&pred, ^{
sharedInstance = [VLCVoutWindowController new];
});
return sharedInstance;
}
- (id)init
{
self = [super init];
o_vout_dict = [[NSMutableDictionary alloc] init];
o_keyboard_backlight = [[KeyboardBacklight alloc] init];
i_currentWindowLevel = NSNormalWindowLevel;
_currentStatusWindowLevel = NSFloatingWindowLevel;
if (self) {
atomic_store(&b_intf_starting, true);
o_vout_dict = [[NSMutableDictionary alloc] init];
o_keyboard_backlight = [[KeyboardBacklight alloc] init];
i_currentWindowLevel = NSNormalWindowLevel;
_currentStatusWindowLevel = NSFloatingWindowLevel;
}
return self;
}
......
/*****************************************************************************
* coredialogs.m: Mac OS X Core Dialogs
*****************************************************************************
* Copyright (C) 2005-2012 VLC authors and VideoLAN
* Copyright (C) 2005-2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Derk-Jan Hartman <hartman at videolan dot org>
......@@ -29,9 +29,56 @@
/* for the icon in our custom error panel */
#import <ApplicationServices/ApplicationServices.h>
/*****************************************************************************
* VLCCoreDialogProvider implementation
*****************************************************************************/
static void updateProgressPanel (void *, const char *, float);
static bool checkProgressPanel (void *);
static void destroyProgressPanel (void *);
static int DialogCallback(vlc_object_t *p_this, const char *type, vlc_value_t previous, vlc_value_t value, void *data)
{
@autoreleasepool {
if ([[NSString stringWithUTF8String:type] isEqualToString: @"dialog-progress-bar"]) {
/* the progress panel needs to update itself and therefore wants special treatment within this context */
dialog_progress_bar_t *p_dialog = (dialog_progress_bar_t *)value.p_address;
p_dialog->pf_update = updateProgressPanel;
p_dialog->pf_check = checkProgressPanel;
p_dialog->pf_destroy = destroyProgressPanel;
p_dialog->p_sys = VLCIntf->p_libvlc;
}
NSValue *o_value = [NSValue valueWithPointer:value.p_address];
[[VLCCoreDialogProvider sharedInstance] performEventWithObject: o_value ofType: type];
return VLC_SUCCESS;
}
}
void updateProgressPanel (void *priv, const char *text, float value)
{
@autoreleasepool {
NSString *o_txt = toNSStr(text);
dispatch_async(dispatch_get_main_queue(), ^{
[[VLCCoreDialogProvider sharedInstance] updateProgressPanelWithText: o_txt andNumber: (double)(value * 1000.)];
});
}
}
void destroyProgressPanel (void *priv)
{
@autoreleasepool {
if ([[NSApplication sharedApplication] isRunning])
[[VLCCoreDialogProvider sharedInstance] performSelectorOnMainThread:@selector(destroyProgressPanel) withObject:nil waitUntilDone:YES];
}
}
bool checkProgressPanel (void *priv)
{
@autoreleasepool {
return [[VLCCoreDialogProvider sharedInstance] progressCancelled];
}
}
@interface VLCCoreDialogProvider()
{
ErrorWindowController *o_error_panel;
......@@ -52,6 +99,39 @@
return sharedInstance;
}
- (instancetype)init
{
self = [super init];
if (self) {
intf_thread_t *p_intf = VLCIntf;
/* subscribe to various interactive dialogues */
var_Create(p_intf, "dialog-error", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-error", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-critical", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-critical", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-login", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-login", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-question", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-question", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-progress-bar", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-progress-bar", DialogCallback, (__bridge void *)self);
dialog_Register(p_intf);
}
return self;
}
- (void)dealloc
{
intf_thread_t *p_intf = VLCIntf;
dialog_Unregister(p_intf);
var_DelCallback(p_intf, "dialog-error", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-critical", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-login", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-question", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-progress-bar", DialogCallback, (__bridge void *)self);
}
-(void)awakeFromNib
{
_progressCancelled = NO;
......
/*****************************************************************************
* helpers.h
*****************************************************************************
* Copyright (C) 2009-2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan org>
* Felix Paul Kühne <fkuehne at videolan dot org>
* David Fuhrmann <david dot fuhrmann at googlemail dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "intf.h"
#import "VideoView.h"
static inline input_thread_t *getInput(void)
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return NULL;
return pl_CurrentInput(p_intf);
}
static inline vout_thread_t *getVout(void)
{
input_thread_t *p_input = getInput();
if (!p_input)
return NULL;
vout_thread_t *p_vout = input_GetVout(p_input);
vlc_object_release(p_input);
return p_vout;
}
static inline vout_thread_t *getVoutForActiveWindow(void)
{
vout_thread_t *p_vout = nil;
id currentWindow = [NSApp keyWindow];
if ([currentWindow respondsToSelector:@selector(videoView)]) {
VLCVoutView *videoView = [currentWindow videoView];
if (videoView) {
p_vout = [videoView voutThread];
}
}
if (!p_vout)
p_vout = getVout();
return p_vout;
}
static inline audio_output_t *getAout(void)
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return NULL;
return playlist_GetAout(pl_Get(p_intf));
}
/*****************************************************************************
* intf-prefs.h
*****************************************************************************
* Copyright (C) 2001-2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "intf.h"
@interface VLCMain (OldPrefs)
- (void)private_resetAndReinitializeUserDefaults;
- (void)removeOldPreferences;
@end
/*****************************************************************************
* intf-prefs.m
*****************************************************************************
* Copyright (C) 2001-2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan org>
* Felix Paul Kühne <fkuehne at videolan dot org>
* David Fuhrmann <david dot fuhrmann at googlemail dot com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "intf-prefs.h"
#import "CoreInteraction.h"
@implementation VLCMain(OldPrefs)
static NSString * kVLCPreferencesVersion = @"VLCPreferencesVersion";
static const int kCurrentPreferencesVersion = 3;
+ (void)initialize
{
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCurrentPreferencesVersion]
forKey:kVLCPreferencesVersion];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
}
- (void)private_resetAndReinitializeUserDefaults
{
// note that [NSUserDefaults resetStandardUserDefaults] will NOT correctly reset to the defaults
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
// set correct version to avoid question about outdated config
[[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)removeOldPreferences
{
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
int version = [defaults integerForKey:kVLCPreferencesVersion];
/*
* Store version explicitely in file, for ease of debugging.
* Otherwise, the value will be just defined at app startup,
* as initialized above.
*/
[defaults setInteger:version forKey:kVLCPreferencesVersion];
if (version >= kCurrentPreferencesVersion)
return;
if (version == 1) {
[defaults setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
[defaults synchronize];
if (![[VLCCoreInteraction sharedInstance] fixPreferences])
return;
else
config_SaveConfigFile(VLCIntf); // we need to do manually, since we won't quit libvlc cleanly
} else if (version == 2) {
/* version 2 (used by VLC 2.0.x and early versions of 2.1) can lead to exceptions within 2.1 or later
* so we reset the OS X specific prefs here - in practice, no user will notice */
[self resetAndReinitializeUserDefaults];
} else {
NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
NSUserDomainMask, YES);
if (!libraries || [libraries count] == 0) return;
NSString * preferences = [[libraries firstObject] stringByAppendingPathComponent:@"Preferences"];
int res = NSRunInformationalAlertPanel(_NS("Remove old preferences?"),
_NS("We just found an older version of VLC's preferences files."),
_NS("Move To Trash and Relaunch VLC"), _NS("Ignore"), nil, nil);
if (res != NSOKButton) {
[defaults setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
return;
}
// Do NOT add the current plist file here as this would conflict with caching.
// Instead, just reset below.
NSArray * ourPreferences = [NSArray arrayWithObjects:@"org.videolan.vlc", @"VLC", nil];
/* Move the file to trash one by one. Using above array the method would stop after first file
not found. */
for (NSString *file in ourPreferences) {
[[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:preferences destination:@"" files:[NSArray arrayWithObject:file] tag:nil];
}
[self resetAndReinitializeUserDefaults];
}
/* Relaunch now */
const char * path = [[[NSBundle mainBundle] executablePath] UTF8String];
/* For some reason we need to fork(), not just execl(), which reports a ENOTSUP then. */
if (fork() != 0) {
exit(0);
}
execl(path, path, NULL);
}
@end
\ No newline at end of file
/*****************************************************************************
* intf.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2002-2014 VLC authors and VideoLAN
* Copyright (C) 2002-2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <hartman at videolan dot org>
* Authors: Derk-Jan Hartman <hartman at videolan dot org>
* Felix Paul Kühne <fkuehne at videolan dot org>
* David Fuhrmann <david dot fuhrmann at googlemail dot com>
* Pierre d'Herbemont <pdherbemont # videolan org>
......@@ -36,9 +35,9 @@
#import <vlc_aout.h>
#import <vlc_input.h>
#import <vlc_vout_window.h>
#import <vlc_atomic.h>
#import <Cocoa/Cocoa.h>
#import "SPMediaKeyTap.h" /* for the media key support */
#import "misc.h"
#import "MainWindow.h"
#import "VLCVoutWindowController.h"
......@@ -49,12 +48,6 @@
*****************************************************************************/
#define VLCIntf [[VLCMain sharedInstance] intf]
// You need to release those objects after use
input_thread_t *getInput(void);
vout_thread_t *getVout(void);
vout_thread_t *getVoutForActiveWindow(void);
audio_output_t *getAout(void);
static NSString * VLCInputChangedNotification = @"VLCInputChangedNotification";
/*****************************************************************************
......@@ -65,8 +58,14 @@ static NSString * VLCInputChangedNotification = @"VLCInputChangedNotification";
@class VLCControls;
@class VLCMainMenu;
@class VLCPlaylist;
@class InputManager;
@class VLCInputManager;
@class ResumeDialogController;
@class VLCSimplePrefs;
@class VLCPrefs;
@class VLCCoreDialogProvider;
@class VLCEyeTVController;
@class VLCBookmarks;
@class VLCOpen;
@interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
{
......@@ -86,32 +85,23 @@ static NSString * VLCInputChangedNotification = @"VLCInputChangedNotification";
- (VLCMainMenu *)mainMenu;
- (VLCMainWindow *)mainWindow;
- (id)controls;
- (id)bookmarks;
- (id)open;
- (id)simplePreferences;
- (id)preferences;
- (VLCControls *)controls;
- (VLCBookmarks *)bookmarks;
- (VLCOpen *)open;
- (VLCSimplePrefs *)simplePreferences;
- (VLCPrefs *)preferences;
- (VLCPlaylist *)playlist;
- (id)coreDialogProvider;
- (VLCCoreDialogProvider *)coreDialogProvider;
- (ResumeDialogController *)resumeDialog;
- (id)eyeTVController;
- (id)appleRemoteController;
- (VLCEyeTVController *)eyeTVController;
- (VLCInputManager *)inputManager;
- (void)setActiveVideoPlayback:(BOOL)b_value;
- (BOOL)activeVideoPlayback;
- (void)applicationWillTerminate:(NSNotification *)notification;
- (void)updateCurrentlyUsedHotkeys;
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force;
- (void)resetAndReinitializeUserDefaults;
- (void)plItemUpdated;
- (void)playbackModeUpdated;
- (void)showFullscreenController;
- (void)updateTogglePlaylistState;
- (void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event;
- (void)resetAndReinitializeUserDefaults;
- (BOOL)isTerminating;
@end
......@@ -124,3 +114,5 @@ static NSString * VLCInputChangedNotification = @"VLCInputChangedNotification";
@interface VLCApplication : NSApplication
@end
#import "helpers.h"
/*****************************************************************************
* intf.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2002-2013 VLC authors and VideoLAN
* Copyright (C) 2002-2015 VLC authors and VideoLAN
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <hartman at videolan.org>
* Authors: Derk-Jan Hartman <hartman at videolan.org>
* Felix Paul Kühne <fkuehne at videolan dot org>
* Pierre d'Herbemont <pdherbemont # videolan org>
* David Fuhrmann <david dot fuhrmann at googlemail dot com>
......@@ -41,9 +40,6 @@
#include <vlc_keys.h>
#include <vlc_dialog.h>
#include <vlc_url.h>
#include <vlc_modules.h>
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
#include <unistd.h> /* execl() */
#import "CompatibilityFixes.h"
......@@ -57,18 +53,17 @@
#import "open.h"
#import "bookmarks.h"
#import "coredialogs.h"
#import "AppleRemote.h"
#import "eyetv.h"
#import "simple_prefs.h"
#import "CoreInteraction.h"
#import "TrackSynchronization.h"
#import "ExtensionsManager.h"
#import "BWQuincyManager.h"
#import "ControlsBar.h"
#import "ResumeDialogController.h"
#import "VideoEffects.h"
#import "AudioEffects.h"
#import "intf-prefs.h"
#ifdef HAVE_SPARKLE
#import <Sparkle/Sparkle.h> /* we're the update delegate */
......@@ -78,42 +73,28 @@
* Local prototypes.
*****************************************************************************/
static void updateProgressPanel (void *, const char *, float);
static bool checkProgressPanel (void *);
static void destroyProgressPanel (void *);
#pragma mark -
#pragma mark VLC Interface Object Callbacks
static atomic_bool b_intf_starting = ATOMIC_VAR_INIT(false);
static NSLock * o_vout_provider_lock = nil;
/*****************************************************************************
* OpenIntf: initialize interface
*****************************************************************************/
int OpenIntf (vlc_object_t *p_this)
{
@autoreleasepool {
[VLCApplication sharedApplication];
intf_thread_t *p_intf = (intf_thread_t*) p_this;
msg_Dbg(p_intf, "Starting macosx interface");
[VLCApplication sharedApplication];
o_vout_provider_lock = [[NSLock alloc] init];
[[VLCMain sharedInstance] setIntf: p_intf];
[NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
[VLCVoutWindowController sharedInstance];
[NSBundle loadNibNamed:@"MainWindow" owner: [VLCMain sharedInstance]];
[[[VLCMain sharedInstance] mainWindow] makeKeyAndOrderFront:nil];
[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
[NSBundle loadNibNamed:@"MainWindow" owner:[VLCMain sharedInstance]];
atomic_store(&b_intf_starting, true);
[[[VLCMain sharedInstance] mainWindow] makeKeyAndOrderFront:nil];
return VLC_SUCCESS;
}
......@@ -124,241 +105,12 @@ void CloseIntf (vlc_object_t *p_this)
@autoreleasepool {
msg_Dbg(p_this, "Closing macosx interface");
[[VLCMain sharedInstance] applicationWillTerminate:nil];
o_vout_provider_lock = nil;
}
}
static int WindowControl(vout_window_t *, int i_query, va_list);
int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
{
@autoreleasepool {
if (cfg->type != VOUT_WINDOW_TYPE_INVALID
&& cfg->type != VOUT_WINDOW_TYPE_NSOBJECT)
return VLC_EGENERIC;
msg_Dbg(p_wnd, "Opening video window");
if (!atomic_load(&b_intf_starting)) {
msg_Err(p_wnd, "Cannot create vout as Mac OS X interface was not found");
return VLC_EGENERIC;
}
NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
[o_vout_provider_lock lock];
VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
if (!o_vout_controller) {
[o_vout_provider_lock unlock];
return VLC_EGENERIC;
}
SEL sel = @selector(setupVoutForWindow:withProposedVideoViewPosition:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
[inv setTarget:o_vout_controller];
[inv setSelector:sel];
[inv setArgument:&p_wnd atIndex:2]; // starting at 2!
[inv setArgument:&proposedVideoViewPosition atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:YES];
VLCVoutView *videoView = nil;
[inv getReturnValue:&videoView];
// this method is not supposed to fail
assert(videoView != nil);
msg_Dbg(VLCIntf, "returning videoview with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height);
p_wnd->handle.nsobject = (void *)CFBridgingRetain(videoView);
[o_vout_provider_lock unlock];
p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT;
p_wnd->control = WindowControl;
return VLC_SUCCESS;
}
}
static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
{
@autoreleasepool {
[o_vout_provider_lock lock];
VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
if (!o_vout_controller) {
[o_vout_provider_lock unlock];
return VLC_EGENERIC;
}
switch(i_query) {
case VOUT_WINDOW_SET_STATE:
{
unsigned i_state = va_arg(args, unsigned);
if (i_state & VOUT_WINDOW_STATE_BELOW)
{
msg_Dbg(p_wnd, "Ignore change to VOUT_WINDOW_STATE_BELOW");
goto out;
}
NSInteger i_cooca_level = NSNormalWindowLevel;
if (i_state & VOUT_WINDOW_STATE_ABOVE)
i_cooca_level = NSStatusWindowLevel;
SEL sel = @selector(setWindowLevel:forWindow:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
[inv setTarget:o_vout_controller];
[inv setSelector:sel];
[inv setArgument:&i_cooca_level atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:NO];
break;
}
case VOUT_WINDOW_SET_SIZE:
{
unsigned int i_width = va_arg(args, unsigned int);
unsigned int i_height = va_arg(args, unsigned int);
NSSize newSize = NSMakeSize(i_width, i_height);
SEL sel = @selector(setNativeVideoSize:forWindow:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
[inv setTarget:o_vout_controller];
[inv setSelector:sel];
[inv setArgument:&newSize atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:NO];
break;
}
case VOUT_WINDOW_SET_FULLSCREEN:
{
if (var_InheritBool(VLCIntf, "video-wallpaper")) {
msg_Dbg(p_wnd, "Ignore fullscreen event as video-wallpaper is on");
goto out;
}
int i_full = va_arg(args, int);
BOOL b_animation = YES;
SEL sel = @selector(setFullscreen:forWindow:withAnimation:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
[inv setTarget:o_vout_controller];
[inv setSelector:sel];
[inv setArgument:&i_full atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
[inv setArgument:&b_animation atIndex:4];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil
waitUntilDone:NO];
break;
}
default:
{
msg_Warn(p_wnd, "unsupported control query");
[o_vout_provider_lock unlock];
return VLC_EGENERIC;
}
}
out:
[o_vout_provider_lock unlock];
return VLC_SUCCESS;
}
}
void WindowClose(vout_window_t *p_wnd)
{
@autoreleasepool {
[o_vout_provider_lock lock];
VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
if (!o_vout_controller) {
[o_vout_provider_lock unlock];
return;
}
[o_vout_controller performSelectorOnMainThread:@selector(removeVoutforDisplay:) withObject:[NSValue valueWithPointer:p_wnd] waitUntilDone:NO];
[o_vout_provider_lock unlock];
}
}
#pragma mark -
#pragma mark Variables Callback
/**
* Callback for item-change variable. Is triggered after update of duration or metadata.
*/
static int PLItemUpdated(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(plItemUpdated) withObject:nil waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int PLItemAppended(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
playlist_add_t *p_add = new_val.p_address;
NSArray *o_val = [NSArray arrayWithObjects:[NSNumber numberWithInt:p_add->i_node], [NSNumber numberWithInt:p_add->i_item], nil];
[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(plItemAppended:) withObject:o_val waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int PLItemRemoved(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
NSNumber *o_val = [NSNumber numberWithInt:new_val.i_int];
[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(plItemRemoved:) withObject:o_val waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int PlaybackModeUpdated(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(playbackModeUpdated) withObject:nil waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int VolumeUpdated(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
dispatch_async(dispatch_get_main_queue(), ^{
[[[VLCMain sharedInstance] mainWindow] updateVolumeSlider];
});
return VLC_SUCCESS;
}
}
static int BossCallback(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
dispatch_async(dispatch_get_main_queue(), ^{
[[VLCCoreInteraction sharedInstance] pause];
[[VLCApplication sharedApplication] hide:nil];
});
return VLC_SUCCESS;
}
}
/*****************************************************************************
* ShowController: Callback triggered by the show-intf playlist variable
* through the ShowIntf-control-intf, to let us show the controller-win;
......@@ -387,120 +139,14 @@ static int ShowController(vlc_object_t *p_this, const char *psz_variable,
}
}
/*****************************************************************************
* DialogCallback: Callback triggered by the "dialog-*" variables
* to let the intf display error and interaction dialogs
*****************************************************************************/
static int DialogCallback(vlc_object_t *p_this, const char *type, vlc_value_t previous, vlc_value_t value, void *data)
{
@autoreleasepool {
if ([[NSString stringWithUTF8String:type] isEqualToString: @"dialog-progress-bar"]) {
/* the progress panel needs to update itself and therefore wants special treatment within this context */
dialog_progress_bar_t *p_dialog = (dialog_progress_bar_t *)value.p_address;
p_dialog->pf_update = updateProgressPanel;
p_dialog->pf_check = checkProgressPanel;
p_dialog->pf_destroy = destroyProgressPanel;
p_dialog->p_sys = VLCIntf->p_libvlc;
}
NSValue *o_value = [NSValue valueWithPointer:value.p_address];
[[[VLCMain sharedInstance] coreDialogProvider] performEventWithObject: o_value ofType: type];
return VLC_SUCCESS;
}
}
void updateProgressPanel (void *priv, const char *text, float value)
{
@autoreleasepool {
NSString *o_txt = toNSStr(text);
dispatch_async(dispatch_get_main_queue(), ^{
[[[VLCMain sharedInstance] coreDialogProvider] updateProgressPanelWithText: o_txt andNumber: (double)(value * 1000.)];
});
}
}
void destroyProgressPanel (void *priv)
{
@autoreleasepool {
if ([[NSApplication sharedApplication] isRunning])
[[[VLCMain sharedInstance] coreDialogProvider] performSelectorOnMainThread:@selector(destroyProgressPanel) withObject:nil waitUntilDone:YES];
}
}
bool checkProgressPanel (void *priv)
{
@autoreleasepool {
return [[[VLCMain sharedInstance] coreDialogProvider] progressCancelled];
}
}
#pragma mark -
#pragma mark Helpers
input_thread_t *getInput(void)
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return NULL;
return pl_CurrentInput(p_intf);
}
vout_thread_t *getVout(void)
{
input_thread_t *p_input = getInput();
if (!p_input)
return NULL;
vout_thread_t *p_vout = input_GetVout(p_input);
vlc_object_release(p_input);
return p_vout;
}
vout_thread_t *getVoutForActiveWindow(void)
{
vout_thread_t *p_vout = nil;
id currentWindow = [NSApp keyWindow];
if ([currentWindow respondsToSelector:@selector(videoView)]) {
VLCVoutView *videoView = [currentWindow videoView];
if (videoView) {
p_vout = [videoView voutThread];
}
}
if (!p_vout)
p_vout = getVout();
return p_vout;
}
audio_output_t *getAout(void)
{
intf_thread_t *p_intf = VLCIntf;
if (!p_intf)
return NULL;
return playlist_GetAout(pl_Get(p_intf));
}
#pragma mark -
#pragma mark Private
@interface VLCMain () <BWQuincyManagerDelegate>
{
intf_thread_t *p_intf; /* The main intf object */
BOOL launched; /* finishedLaunching */
int items_at_launch; /* items in playlist after launch */
VLCMainMenu *o_mainmenu; /* VLCMainMenu */
id o_prefs; /* VLCPrefs */
id o_sprefs; /* VLCSimplePrefs */
id o_open; /* VLCOpen */
id o_coredialogs; /* VLCCoreDialogProvider */
VLCInfo *o_info; /* VLCInformation */
id o_eyetv; /* VLCEyeTVController */
id o_bookmarks; /* VLCBookmarks */
id o_coreinteraction; /* VLCCoreInteraction */
ResumeDialogController *o_resume_dialog;
intf_thread_t *p_intf;
BOOL launched;
int items_at_launch;
BOOL nib_main_loaded; /* main nibfile */
BOOL nib_open_loaded; /* open nibfile */
......@@ -511,26 +157,21 @@ audio_output_t *getAout(void)
BOOL nib_bookmarks_loaded; /* Bookmarks nibfile */
BOOL b_active_videoplayback;
bool b_intf_terminating; /* Makes sure applicationWillTerminate will be called only once */
AppleRemote * o_remote;
BOOL b_remote_button_hold; /* true as long as the user holds the left,right,plus or minus on the remote control */
/* media key support */
BOOL b_mediaKeySupport;
BOOL b_mediakeyJustJumped;
SPMediaKeyTap * o_mediaKeyController;
BOOL b_mediaKeyTrapEnabled;
VLCMainMenu *_mainmenu;
VLCPrefs *_prefs;
VLCSimplePrefs *_sprefs;
VLCOpen *_open;
VLCCoreDialogProvider *_coredialogs;
VLCInfo *_info;
VLCEyeTVController *_eyetv;
VLCBookmarks *_bookmarks;
VLCCoreInteraction *_coreinteraction;
ResumeDialogController *_resume_dialog;
VLCInputManager *_input_manager;
NSArray *o_usedHotkeys;
InputManager *o_input_manager;
bool b_intf_terminating; /* Makes sure applicationWillTerminate will be called only once */
}
- (void)removeOldPreferences;
- (void)resetMediaKeyJump;
- (void)coreChangedMediaKeySupportSetting: (NSNotification *)o_notification;
@end
/*****************************************************************************
......@@ -543,8 +184,8 @@ audio_output_t *getAout(void)
+ (VLCMain *)sharedInstance
{
static VLCMain *sharedInstance = nil;
static dispatch_once_t pred;
static VLCMain *sharedInstance = nil;
dispatch_once(&pred, ^{
sharedInstance = [VLCMain new];
......@@ -559,11 +200,9 @@ audio_output_t *getAout(void)
p_intf = NULL;
o_open = [[VLCOpen alloc] init];
o_coredialogs = [[VLCCoreDialogProvider alloc] init];
o_mainmenu = [[VLCMainMenu alloc] init];
o_coreinteraction = [[VLCCoreInteraction alloc] init];
o_eyetv = [[VLCEyeTVController alloc] init];
_open = [[VLCOpen alloc] init];
_mainmenu = [VLCMainMenu sharedInstance];
_eyetv = [[VLCEyeTVController alloc] init];
/* announce our launch to a potential eyetv plugin */
[[NSDistributedNotificationCenter defaultCenter] postNotificationName: @"VLCOSXGUIInit"
......@@ -592,7 +231,6 @@ audio_output_t *getAout(void)
- (void)awakeFromNib
{
playlist_t *p_playlist;
if (!p_intf) return;
var_Create(p_intf, "intf-change", VLC_VAR_BOOL);
......@@ -602,46 +240,18 @@ audio_output_t *getAout(void)
return;
// TODO: take care of VLCIntf initialization order
o_input_manager = [[InputManager alloc] initWithMain:self];
p_playlist = pl_Get(p_intf);
_input_manager = [[VLCInputManager alloc] initWithMain:self];
var_AddCallback(p_intf->p_libvlc, "intf-toggle-fscontrol", ShowController, (__bridge void *)self);
var_AddCallback(p_intf->p_libvlc, "intf-show", ShowController, (__bridge void *)self);
var_AddCallback(p_intf->p_libvlc, "intf-boss", BossCallback, (__bridge void *)self);
var_AddCallback(p_playlist, "item-change", PLItemUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "playlist-item-append", PLItemAppended, (__bridge void *)self);
var_AddCallback(p_playlist, "playlist-item-deleted", PLItemRemoved, (__bridge void *)self);
var_AddCallback(p_playlist, "random", PlaybackModeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "repeat", PlaybackModeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "loop", PlaybackModeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "volume", VolumeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "mute", VolumeUpdated, (__bridge void *)self);
playlist_t *p_playlist = pl_Get(p_intf);
if ([NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen)
var_SetBool(p_playlist, "fullscreen", YES);
/* load our Shared Dialogs nib */
[NSBundle loadNibNamed:@"SharedDialogs" owner: NSApp];
/* subscribe to various interactive dialogues */
var_Create(p_intf, "dialog-error", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-error", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-critical", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-critical", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-login", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-login", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-question", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-question", DialogCallback, (__bridge void *)self);
var_Create(p_intf, "dialog-progress-bar", VLC_VAR_ADDRESS);
var_AddCallback(p_intf, "dialog-progress-bar", DialogCallback, (__bridge void *)self);
dialog_Register(p_intf);
/* init Apple Remote support */
o_remote = [[AppleRemote alloc] init];
[o_remote setClickCountEnabledButtons: kRemoteButtonPlay];
[o_remote setDelegate: self];
_nativeFullscreenMode = var_InheritBool(p_intf, "macosx-nativefullscreenmode");
if (config_GetInt(VLCIntf, "macosx-icon-change")) {
......@@ -662,6 +272,8 @@ audio_output_t *getAout(void)
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
_coreinteraction = [VLCCoreInteraction sharedInstance];
playlist_t * p_playlist = pl_Get(VLCIntf);
PL_LOCK;
items_at_launch = p_playlist->p_local_category->i_children;
......@@ -690,17 +302,7 @@ audio_output_t *getAout(void)
[quincyManager setDelegate:self];
[quincyManager setCompanyName:@"VideoLAN"];
[self updateCurrentlyUsedHotkeys];
/* init media key support */
b_mediaKeySupport = var_InheritBool(VLCIntf, "macosx-mediakeys");
if (b_mediaKeySupport) {
o_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
[SPMediaKeyTap defaultMediaKeyUserBundleIdentifiers], kMediaKeyUsingBundleIdentifiersDefaultsKey,
nil]];
}
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(coreChangedMediaKeySupportSetting:) name: @"VLCMediaKeySupportSettingChanged" object: nil];
[_coreinteraction updateCurrentlyUsedHotkeys];
[self removeOldPreferences];
......@@ -717,8 +319,8 @@ audio_output_t *getAout(void)
* Thus, call additional updaters as we might miss these events if posted before
* the callbacks are registered.
*/
[o_input_manager inputThreadChanged];
[self playbackModeUpdated];
[_input_manager inputThreadChanged];
[o_playlist playbackModeUpdated];
// respect playlist-autostart
// note that PLAYLIST_PLAY will not stop any playback if already started
......@@ -744,7 +346,7 @@ audio_output_t *getAout(void)
return;
b_intf_terminating = true;
[o_input_manager resumeItunesPlayback:nil];
[_input_manager resumeItunesPlayback:nil];
if (notification == nil)
[[NSNotificationCenter defaultCenter] postNotificationName: NSApplicationWillTerminateNotification object: nil];
......@@ -762,32 +364,15 @@ audio_output_t *getAout(void)
msg_Dbg(p_intf, "Terminating");
/* unsubscribe from the interactive dialogues */
dialog_Unregister(p_intf);
var_DelCallback(p_intf, "dialog-error", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-critical", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-login", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-question", DialogCallback, (__bridge void *)self);
var_DelCallback(p_intf, "dialog-progress-bar", DialogCallback, (__bridge void *)self);
var_DelCallback(p_playlist, "item-change", PLItemUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "playlist-item-append", PLItemAppended, (__bridge void *)self);
var_DelCallback(p_playlist, "playlist-item-deleted", PLItemRemoved, (__bridge void *)self);
var_DelCallback(p_playlist, "random", PlaybackModeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "repeat", PlaybackModeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "loop", PlaybackModeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "volume", VolumeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "mute", VolumeUpdated, (__bridge void *)self);
var_DelCallback(p_intf->p_libvlc, "intf-toggle-fscontrol", ShowController, (__bridge void *)self);
var_DelCallback(p_intf->p_libvlc, "intf-show", ShowController, (__bridge void *)self);
var_DelCallback(p_intf->p_libvlc, "intf-boss", BossCallback, (__bridge void *)self);
/* remove global observer watching for vout device changes correctly */
[[NSNotificationCenter defaultCenter] removeObserver: self];
[o_vout_provider_lock lock];
[_voutController.lock lock];
// closes all open vouts
_voutController = nil;
[o_vout_provider_lock unlock];
[_voutController.lock unlock];
/* unsubscribe from libvlc's debug messages */
vlc_LogSet(p_intf->p_libvlc, NULL, NULL);
......@@ -808,8 +393,8 @@ audio_output_t *getAout(void)
- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
{
[NSApp activateIgnoringOtherApps:YES];
[o_remote stopListening: self];
[[VLCCoreInteraction sharedInstance] stop];
[_coreinteraction stopListeningWithAppleRemote];
[_coreinteraction stop];
}
/* don't be enthusiastic about an update if we currently play a video */
......@@ -822,48 +407,6 @@ audio_output_t *getAout(void)
}
#endif
#pragma mark -
#pragma mark Media Key support
-(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event
{
if (b_mediaKeySupport) {
assert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys);
int keyCode = (([event data1] & 0xFFFF0000) >> 16);
int keyFlags = ([event data1] & 0x0000FFFF);
int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA;
int keyRepeat = (keyFlags & 0x1);
if (keyCode == NX_KEYTYPE_PLAY && keyState == 0)
[[VLCCoreInteraction sharedInstance] playOrPause];
if ((keyCode == NX_KEYTYPE_FAST || keyCode == NX_KEYTYPE_NEXT) && !b_mediakeyJustJumped) {
if (keyState == 0 && keyRepeat == 0)
[[VLCCoreInteraction sharedInstance] next];
else if (keyRepeat == 1) {
[[VLCCoreInteraction sharedInstance] forwardShort];
b_mediakeyJustJumped = YES;
[self performSelector:@selector(resetMediaKeyJump)
withObject: NULL
afterDelay:0.25];
}
}
if ((keyCode == NX_KEYTYPE_REWIND || keyCode == NX_KEYTYPE_PREVIOUS) && !b_mediakeyJustJumped) {
if (keyState == 0 && keyRepeat == 0)
[[VLCCoreInteraction sharedInstance] previous];
else if (keyRepeat == 1) {
[[VLCCoreInteraction sharedInstance] backwardShort];
b_mediakeyJustJumped = YES;
[self performSelector:@selector(resetMediaKeyJump)
withObject: NULL
afterDelay:0.25];
}
}
}
}
#pragma mark -
#pragma mark Other notification
......@@ -874,19 +417,19 @@ audio_output_t *getAout(void)
if (!p_intf)
return;
if (var_InheritBool(p_intf, "macosx-appleremote") == YES)
[o_remote startListening: self];
[_coreinteraction startListeningWithAppleRemote];
}
- (void)applicationDidResignActive:(NSNotification *)aNotification
{
if (!p_intf)
return;
[o_remote stopListening: self];
[_coreinteraction stopListeningWithAppleRemote];
}
/* Triggered when the computer goes to sleep */
- (void)computerWillSleep: (NSNotification *)notification
{
[[VLCCoreInteraction sharedInstance] pause];
[_coreinteraction pause];
}
#pragma mark -
......@@ -949,256 +492,6 @@ audio_output_t *getAout(void)
return YES;
}
#pragma mark -
#pragma mark Apple Remote Control
/* Helper method for the remote control interface in order to trigger forward/backward and volume
increase/decrease as long as the user holds the left/right, plus/minus button */
- (void) executeHoldActionForRemoteButton: (NSNumber*) buttonIdentifierNumber
{
if (b_remote_button_hold) {
switch([buttonIdentifierNumber intValue]) {
case kRemoteButtonRight_Hold:
[[VLCCoreInteraction sharedInstance] forward];
break;
case kRemoteButtonLeft_Hold:
[[VLCCoreInteraction sharedInstance] backward];
break;
case kRemoteButtonVolume_Plus_Hold:
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_UP);
break;
case kRemoteButtonVolume_Minus_Hold:
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_DOWN);
break;
}
if (b_remote_button_hold) {
/* trigger event */
[self performSelector:@selector(executeHoldActionForRemoteButton:)
withObject:buttonIdentifierNumber
afterDelay:0.25];
}
}
}
/* Apple Remote callback */
- (void) appleRemoteButton: (AppleRemoteEventIdentifier)buttonIdentifier
pressedDown: (BOOL) pressedDown
clickCount: (unsigned int) count
{
switch(buttonIdentifier) {
case k2009RemoteButtonFullscreen:
[[VLCCoreInteraction sharedInstance] toggleFullscreen];
break;
case k2009RemoteButtonPlay:
[[VLCCoreInteraction sharedInstance] playOrPause];
break;
case kRemoteButtonPlay:
if (count >= 2)
[[VLCCoreInteraction sharedInstance] toggleFullscreen];
else
[[VLCCoreInteraction sharedInstance] playOrPause];
break;
case kRemoteButtonVolume_Plus:
if (config_GetInt(VLCIntf, "macosx-appleremote-sysvol"))
[NSSound increaseSystemVolume];
else
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_UP);
break;
case kRemoteButtonVolume_Minus:
if (config_GetInt(VLCIntf, "macosx-appleremote-sysvol"))
[NSSound decreaseSystemVolume];
else
if (p_intf)
var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_DOWN);
break;
case kRemoteButtonRight:
if (config_GetInt(VLCIntf, "macosx-appleremote-prevnext"))
[[VLCCoreInteraction sharedInstance] forward];
else
[[VLCCoreInteraction sharedInstance] next];
break;
case kRemoteButtonLeft:
if (config_GetInt(VLCIntf, "macosx-appleremote-prevnext"))
[[VLCCoreInteraction sharedInstance] backward];
else
[[VLCCoreInteraction sharedInstance] previous];
break;
case kRemoteButtonRight_Hold:
case kRemoteButtonLeft_Hold:
case kRemoteButtonVolume_Plus_Hold:
case kRemoteButtonVolume_Minus_Hold:
/* simulate an event as long as the user holds the button */
b_remote_button_hold = pressedDown;
if (pressedDown) {
NSNumber* buttonIdentifierNumber = [NSNumber numberWithInt:buttonIdentifier];
[self performSelector:@selector(executeHoldActionForRemoteButton:)
withObject:buttonIdentifierNumber];
}
break;
case kRemoteButtonMenu:
[o_controls showPosition: self]; //FIXME
break;
case kRemoteButtonPlay_Sleep:
{
NSAppleScript * script = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to sleep"];
[script executeAndReturnError:nil];
break;
}
default:
/* Add here whatever you want other buttons to do */
break;
}
}
#pragma mark -
#pragma mark Key Shortcuts
/*****************************************************************************
* hasDefinedShortcutKey: Check to see if the key press is a defined VLC
* shortcut key. If it is, pass it off to VLC for handling and return YES,
* otherwise ignore it and return NO (where it will get handled by Cocoa).
*****************************************************************************/
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force
{
unichar key = 0;
vlc_value_t val;
unsigned int i_pressed_modifiers = 0;
val.i_int = 0;
i_pressed_modifiers = [o_event modifierFlags];
if (i_pressed_modifiers & NSControlKeyMask)
val.i_int |= KEY_MODIFIER_CTRL;
if (i_pressed_modifiers & NSAlternateKeyMask)
val.i_int |= KEY_MODIFIER_ALT;
if (i_pressed_modifiers & NSShiftKeyMask)
val.i_int |= KEY_MODIFIER_SHIFT;
if (i_pressed_modifiers & NSCommandKeyMask)
val.i_int |= KEY_MODIFIER_COMMAND;
NSString * characters = [o_event charactersIgnoringModifiers];
if ([characters length] > 0) {
key = [[characters lowercaseString] characterAtIndex: 0];
/* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
if (key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask) {
[[VLCCoreInteraction sharedInstance] toggleFullscreen];
return YES;
}
if (!b_force) {
switch(key) {
case NSDeleteCharacter:
case NSDeleteFunctionKey:
case NSDeleteCharFunctionKey:
case NSBackspaceCharacter:
case NSUpArrowFunctionKey:
case NSDownArrowFunctionKey:
case NSEnterCharacter:
case NSCarriageReturnCharacter:
return NO;
}
}
val.i_int |= CocoaKeyToVLC(key);
BOOL b_found_key = NO;
for (NSUInteger i = 0; i < [o_usedHotkeys count]; i++) {
NSString *str = [o_usedHotkeys objectAtIndex:i];
unsigned int i_keyModifiers = [[VLCStringUtility sharedInstance] VLCModifiersToCocoa: str];
if ([[characters lowercaseString] isEqualToString: [[VLCStringUtility sharedInstance] VLCKeyToString: str]] &&
(i_keyModifiers & NSShiftKeyMask) == (i_pressed_modifiers & NSShiftKeyMask) &&
(i_keyModifiers & NSControlKeyMask) == (i_pressed_modifiers & NSControlKeyMask) &&
(i_keyModifiers & NSAlternateKeyMask) == (i_pressed_modifiers & NSAlternateKeyMask) &&
(i_keyModifiers & NSCommandKeyMask) == (i_pressed_modifiers & NSCommandKeyMask)) {
b_found_key = YES;
break;
}
}
if (b_found_key) {
var_SetInteger(p_intf->p_libvlc, "key-pressed", val.i_int);
return YES;
}
}
return NO;
}
- (void)updateCurrentlyUsedHotkeys
{
NSMutableArray *o_tempArray = [[NSMutableArray alloc] init];
/* Get the main Module */
module_t *p_main = module_get_main();
assert(p_main);
unsigned confsize;
module_config_t *p_config;
p_config = module_config_get (p_main, &confsize);
for (size_t i = 0; i < confsize; i++) {
module_config_t *p_item = p_config + i;
if (CONFIG_ITEM(p_item->i_type) && p_item->psz_name != NULL
&& !strncmp(p_item->psz_name , "key-", 4)
&& !EMPTY_STR(p_item->psz_text)) {
if (p_item->value.psz)
[o_tempArray addObject: [NSString stringWithUTF8String:p_item->value.psz]];
}
}
module_config_free (p_config);
o_usedHotkeys = [[NSArray alloc] initWithArray: o_tempArray copyItems: YES];
}
#pragma mark -
#pragma mark Interface updaters
- (void)plItemAppended:(NSArray *)o_val
{
int i_node = [[o_val firstObject] intValue];
int i_item = [[o_val objectAtIndex:1] intValue];
[[[self playlist] model] addItem:i_item withParentNode:i_node];
// update badge in sidebar
[o_mainwindow updateWindow];
[[NSNotificationCenter defaultCenter] postNotificationName: @"VLCMediaKeySupportSettingChanged"
object: nil
userInfo: nil];
}
- (void)plItemRemoved:(NSNumber *)o_val
{
int i_item = [o_val intValue];
[[[self playlist] model] removeItem:i_item];
[[self playlist] deletionCompleted];
// update badge in sidebar
[o_mainwindow updateWindow];
[[NSNotificationCenter defaultCenter] postNotificationName: @"VLCMediaKeySupportSettingChanged"
object: nil
userInfo: nil];
}
- (void)plItemUpdated
{
[o_mainwindow updateName];
if (o_info != NULL)
[o_info updateMetadata];
}
- (void)showFullscreenController
{
// defer selector here (possibly another time) to ensure that keyWindow is set properly
......@@ -1206,29 +499,6 @@ audio_output_t *getAout(void)
[o_mainwindow performSelectorOnMainThread:@selector(showFullscreenController) withObject:nil waitUntilDone:NO];
}
- (void)playbackModeUpdated
{
playlist_t * p_playlist = pl_Get(VLCIntf);
bool loop = var_GetBool(p_playlist, "loop");
bool repeat = var_GetBool(p_playlist, "repeat");
VLCMainWindowControlsBar *controlsBar = (VLCMainWindowControlsBar *)[o_mainwindow controlsBar];
if (repeat) {
[controlsBar setRepeatOne];
[o_mainmenu setRepeatOne];
} else if (loop) {
[controlsBar setRepeatAll];
[o_mainmenu setRepeatAll];
} else {
[controlsBar setRepeatOff];
[o_mainmenu setRepeatOff];
}
[controlsBar setShuffle];
[o_mainmenu setShuffle];
}
- (void)setActiveVideoPlayback:(BOOL)b_value
{
assert([NSThread isMainThread]);
......@@ -1239,7 +509,7 @@ audio_output_t *getAout(void)
}
// update sleep blockers
[o_input_manager playbackStatusUpdated];
[_input_manager playbackStatusUpdated];
}
#pragma mark -
......@@ -1247,7 +517,7 @@ audio_output_t *getAout(void)
- (VLCMainMenu *)mainMenu
{
return o_mainmenu;
return _mainmenu;
}
- (VLCMainWindow *)mainWindow
......@@ -1255,50 +525,55 @@ audio_output_t *getAout(void)
return o_mainwindow;
}
- (id)controls
- (VLCControls *)controls
{
return o_controls;
}
- (id)bookmarks
- (VLCInputManager *)inputManager
{
if (!o_bookmarks)
o_bookmarks = [[VLCBookmarks alloc] init];
return _input_manager;
}
- (VLCBookmarks *)bookmarks
{
if (!_bookmarks)
_bookmarks = [[VLCBookmarks alloc] init];
if (!nib_bookmarks_loaded)
nib_bookmarks_loaded = [NSBundle loadNibNamed:@"Bookmarks" owner:o_bookmarks];
nib_bookmarks_loaded = [NSBundle loadNibNamed:@"Bookmarks" owner:_bookmarks];
return o_bookmarks;
return _bookmarks;
}
- (id)open
- (VLCOpen *)open
{
if (!nib_open_loaded)
nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner: o_open];
nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner: _open];
return o_open;
return _open;
}
- (id)simplePreferences
- (VLCSimplePrefs *)simplePreferences
{
if (!o_sprefs)
o_sprefs = [[VLCSimplePrefs alloc] init];
if (!_sprefs)
_sprefs = [[VLCSimplePrefs alloc] init];
if (!nib_prefs_loaded)
nib_prefs_loaded = [NSBundle loadNibNamed:@"SimplePreferences" owner: o_sprefs];
nib_prefs_loaded = [NSBundle loadNibNamed:@"SimplePreferences" owner: _sprefs];
return o_sprefs;
return _sprefs;
}
- (id)preferences
- (VLCPrefs *)preferences
{
if (!o_prefs)
o_prefs = [[VLCPrefs alloc] init];
if (!_prefs)
_prefs = [[VLCPrefs alloc] init];
if (!nib_prefs_loaded)
nib_prefs_loaded = [NSBundle loadNibNamed:@"Preferences" owner: o_prefs];
nib_prefs_loaded = [NSBundle loadNibNamed:@"Preferences" owner: _prefs];
return o_prefs;
return _prefs;
}
- (VLCPlaylist *)playlist
......@@ -1306,31 +581,27 @@ audio_output_t *getAout(void)
return o_playlist;
}
- (id)coreDialogProvider
- (VLCCoreDialogProvider *)coreDialogProvider
{
_coredialogs = [VLCCoreDialogProvider sharedInstance];
if (!nib_coredialogs_loaded) {
nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: NSApp];
nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: _coredialogs];
}
return o_coredialogs;
return _coredialogs;
}
- (ResumeDialogController *)resumeDialog
{
if (!o_resume_dialog)
o_resume_dialog = [[ResumeDialogController alloc] init];
if (!_resume_dialog)
_resume_dialog = [[ResumeDialogController alloc] init];
return o_resume_dialog;
return _resume_dialog;
}
- (id)eyeTVController
- (VLCEyeTVController *)eyeTVController
{
return o_eyetv;
}
- (id)appleRemoteController
{
return o_remote;
return _eyetv;
}
- (BOOL)activeVideoPlayback
......@@ -1338,132 +609,9 @@ audio_output_t *getAout(void)
return b_active_videoplayback;
}
#pragma mark -
#pragma mark Remove old prefs
static NSString * kVLCPreferencesVersion = @"VLCPreferencesVersion";
static const int kCurrentPreferencesVersion = 3;
+ (void)initialize
{
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCurrentPreferencesVersion]
forKey:kVLCPreferencesVersion];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
}
- (void)resetAndReinitializeUserDefaults
{
// note that [NSUserDefaults resetStandardUserDefaults] will NOT correctly reset to the defaults
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
// set correct version to avoid question about outdated config
[[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)removeOldPreferences
{
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
int version = [defaults integerForKey:kVLCPreferencesVersion];
/*
* Store version explicitely in file, for ease of debugging.
* Otherwise, the value will be just defined at app startup,
* as initialized above.
*/
[defaults setInteger:version forKey:kVLCPreferencesVersion];
if (version >= kCurrentPreferencesVersion)
return;
if (version == 1) {
[defaults setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
[defaults synchronize];
if (![[VLCCoreInteraction sharedInstance] fixPreferences])
return;
else
config_SaveConfigFile(VLCIntf); // we need to do manually, since we won't quit libvlc cleanly
} else if (version == 2) {
/* version 2 (used by VLC 2.0.x and early versions of 2.1) can lead to exceptions within 2.1 or later
* so we reset the OS X specific prefs here - in practice, no user will notice */
[self resetAndReinitializeUserDefaults];
} else {
NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
NSUserDomainMask, YES);
if (!libraries || [libraries count] == 0) return;
NSString * preferences = [[libraries firstObject] stringByAppendingPathComponent:@"Preferences"];
int res = NSRunInformationalAlertPanel(_NS("Remove old preferences?"),
_NS("We just found an older version of VLC's preferences files."),
_NS("Move To Trash and Relaunch VLC"), _NS("Ignore"), nil, nil);
if (res != NSOKButton) {
[defaults setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
return;
}
// Do NOT add the current plist file here as this would conflict with caching.
// Instead, just reset below.
NSArray * ourPreferences = [NSArray arrayWithObjects:@"org.videolan.vlc", @"VLC", nil];
/* Move the file to trash one by one. Using above array the method would stop after first file
not found. */
for (NSString *file in ourPreferences) {
[[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:preferences destination:@"" files:[NSArray arrayWithObject:file] tag:nil];
}
[self resetAndReinitializeUserDefaults];
}
/* Relaunch now */
const char * path = [[[NSBundle mainBundle] executablePath] UTF8String];
/* For some reason we need to fork(), not just execl(), which reports a ENOTSUP then. */
if (fork() != 0) {
exit(0);
}
execl(path, path, NULL);
}
#pragma mark -
#pragma mark Playlist toggling
- (void)updateTogglePlaylistState
{
[[self playlist] outlineViewSelectionDidChange: NULL];
}
#pragma mark - media keys
- (void)resetMediaKeyJump
{
b_mediakeyJustJumped = NO;
}
- (void)coreChangedMediaKeySupportSetting: (NSNotification *)o_notification
{
b_mediaKeySupport = var_InheritBool(VLCIntf, "macosx-mediakeys");
if (b_mediaKeySupport && !o_mediaKeyController)
o_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
if (b_mediaKeySupport && ([[[[VLCMain sharedInstance] playlist] model] hasChildren] ||
[o_input_manager hasInput])) {
if (!b_mediaKeyTrapEnabled) {
b_mediaKeyTrapEnabled = YES;
msg_Dbg(p_intf, "Enable media key support");
[o_mediaKeyController startWatchingMediaKeys];
}
} else {
if (b_mediaKeyTrapEnabled) {
b_mediaKeyTrapEnabled = NO;
msg_Dbg(p_intf, "Disable media key support");
[o_mediaKeyController stopWatchingMediaKeys];
}
}
[self private_resetAndReinitializeUserDefaults];
}
@end
......
......@@ -75,6 +75,8 @@
- (IBAction)searchItem:(id)sender;
- (void)playlistUpdated;
- (void)playbackModeUpdated;
- (void)updateTogglePlaylistState;
- (void)outlineViewSelectionDidChange:(NSNotification *)notification;
- (void)sortNode:(int)i_mode;
......
......@@ -50,6 +50,7 @@
#import "open.h"
#import "MainMenu.h"
#import "CoreInteraction.h"
#import "ControlsBar.h"
#import "ResumeDialogController.h"
......@@ -57,6 +58,61 @@
#import <vlc_interface.h>
#include <vlc_url.h>
static int PLItemUpdated(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
[[[VLCMain sharedInstance] playlist] performSelectorOnMainThread:@selector(plItemUpdated) withObject:nil waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int PLItemAppended(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
playlist_add_t *p_add = new_val.p_address;
NSArray *o_val = [NSArray arrayWithObjects:[NSNumber numberWithInt:p_add->i_node], [NSNumber numberWithInt:p_add->i_item], nil];
[[[VLCMain sharedInstance] playlist] performSelectorOnMainThread:@selector(plItemAppended:) withObject:o_val waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int PLItemRemoved(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
NSNumber *o_val = [NSNumber numberWithInt:new_val.i_int];
[[[VLCMain sharedInstance] playlist] performSelectorOnMainThread:@selector(plItemRemoved:) withObject:o_val waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int PlaybackModeUpdated(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
[[[VLCMain sharedInstance] playlist] performSelectorOnMainThread:@selector(playbackModeUpdated) withObject:nil waitUntilDone:NO];
return VLC_SUCCESS;
}
}
static int VolumeUpdated(vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
@autoreleasepool {
dispatch_async(dispatch_get_main_queue(), ^{
[[[VLCMain sharedInstance] mainWindow] updateVolumeSlider];
});
return VLC_SUCCESS;
}
}
/*****************************************************************************
* VLCPlaylistView implementation
*****************************************************************************/
......@@ -179,6 +235,36 @@
[defaults registerDefaults:appDefaults];
}
- (instancetype)init
{
self = [super init];
if (self) {
playlist_t *p_playlist = pl_Get(VLCIntf);
var_AddCallback(p_playlist, "item-change", PLItemUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "playlist-item-append", PLItemAppended, (__bridge void *)self);
var_AddCallback(p_playlist, "playlist-item-deleted", PLItemRemoved, (__bridge void *)self);
var_AddCallback(p_playlist, "random", PlaybackModeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "repeat", PlaybackModeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "loop", PlaybackModeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "volume", VolumeUpdated, (__bridge void *)self);
var_AddCallback(p_playlist, "mute", VolumeUpdated, (__bridge void *)self);
}
return self;
}
- (void)dealloc
{
playlist_t *p_playlist = pl_Get(VLCIntf);
var_DelCallback(p_playlist, "item-change", PLItemUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "playlist-item-append", PLItemAppended, (__bridge void *)self);
var_DelCallback(p_playlist, "playlist-item-deleted", PLItemRemoved, (__bridge void *)self);
var_DelCallback(p_playlist, "random", PlaybackModeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "repeat", PlaybackModeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "loop", PlaybackModeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "volume", VolumeUpdated, (__bridge void *)self);
var_DelCallback(p_playlist, "mute", VolumeUpdated, (__bridge void *)self);
}
- (PLModel *)model
{
return o_model;
......@@ -284,6 +370,73 @@
[o_outline_view reloadData];
}
- (void)plItemAppended:(NSArray *)o_val
{
int i_node = [[o_val firstObject] intValue];
int i_item = [[o_val objectAtIndex:1] intValue];
[[self model] addItem:i_item withParentNode:i_node];
// update badge in sidebar
[[[VLCMain sharedInstance] mainWindow] updateWindow];
[[NSNotificationCenter defaultCenter] postNotificationName: @"VLCMediaKeySupportSettingChanged"
object: nil
userInfo: nil];
}
- (void)plItemRemoved:(NSNumber *)o_val
{
int i_item = [o_val intValue];
[[self model] removeItem:i_item];
[self deletionCompleted];
// update badge in sidebar
[[[VLCMain sharedInstance] mainWindow] updateWindow];
[[NSNotificationCenter defaultCenter] postNotificationName: @"VLCMediaKeySupportSettingChanged"
object: nil
userInfo: nil];
}
- (void)plItemUpdated
{
VLCMain *instance = [VLCMain sharedInstance];
[[instance mainWindow] updateName];
[[VLCInfo sharedInstance] updateMetadata];
}
- (void)playbackModeUpdated
{
playlist_t * p_playlist = pl_Get(VLCIntf);
bool loop = var_GetBool(p_playlist, "loop");
bool repeat = var_GetBool(p_playlist, "repeat");
VLCMainWindowControlsBar *controlsBar = (VLCMainWindowControlsBar *)[[[VLCMain sharedInstance] mainWindow] controlsBar];
VLCMainMenu *mainMenu = [[VLCMain sharedInstance] mainMenu];
if (repeat) {
[controlsBar setRepeatOne];
[mainMenu setRepeatOne];
} else if (loop) {
[controlsBar setRepeatAll];
[mainMenu setRepeatAll];
} else {
[controlsBar setRepeatOff];
[mainMenu setRepeatOff];
}
[controlsBar setShuffle];
[mainMenu setShuffle];
}
- (void)updateTogglePlaylistState
{
[self outlineViewSelectionDidChange: NULL];
}
- (void)outlineViewSelectionDidChange:(NSNotification *)notification
{
// // FIXME: unsafe
......
......@@ -35,6 +35,7 @@
#import <vlc_config_cat.h>
#import "misc.h"
#import "intf.h"
#import "intf-prefs.h"
#import "AppleRemote.h"
#import "CoreInteraction.h"
......@@ -948,9 +949,9 @@ static inline void save_string_list(intf_thread_t * p_intf, id object, const cha
/* activate stuff without restart */
if ([_intf_appleremoteCheckbox state] == YES)
[[[VLCMain sharedInstance] appleRemoteController] startListening: [VLCMain sharedInstance]];
[[VLCCoreInteraction sharedInstance] startListeningWithAppleRemote];
else
[[[VLCMain sharedInstance] appleRemoteController] stopListening: [VLCMain sharedInstance]];
[[VLCCoreInteraction sharedInstance] stopListeningWithAppleRemote];
_intfSettingChanged = NO;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment