/*****************************************************************************
* intf.m: MacOS X interface module
*****************************************************************************
- * Copyright (C) 2002-2012 VLC authors and VideoLAN
+ * Copyright (C) 2002-2013 VLC authors and VideoLAN
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
* Derk-Jan Hartman <hartman at 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
#import "CoreInteraction.h"
#import "TrackSynchronization.h"
#import "VLCVoutWindowController.h"
+#import "ExtensionsManager.h"
+
+#import "VideoEffects.h"
+#import "AudioEffects.h"
#import <AddressBook/AddressBook.h> /* for crashlog send mechanism */
#import <Sparkle/Sparkle.h> /* we're the update delegate */
msg_Err(p_wnd, "Mac OS X interface not found");
return VLC_EGENERIC;
}
-
NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
int i_full = 1;
SEL sel = @selector(setFullscreen:forWindow:);
- NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[VLCMain sharedInstance] methodSignatureForSelector:sel]];
- [inv setTarget:[VLCMain sharedInstance]];
+ NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
+ [inv setTarget:[[VLCMain sharedInstance] voutController]];
[inv setSelector:sel];
[inv setArgument:&i_full atIndex:2];
[inv setArgument:&p_wnd atIndex:3];
case VOUT_WINDOW_SET_STATE:
{
unsigned i_state = va_arg(args, unsigned);
- [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(setWindowLevel:) withObject:[NSNumber numberWithUnsignedInt:i_state] waitUntilDone:NO];
+
+ 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:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
+ [inv setTarget:[[VLCMain sharedInstance] 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];
+
return VLC_SUCCESS;
}
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);
+ NSSize newSize = NSMakeSize(i_width, i_height);
SEL sel = @selector(setNativeVideoSize:forWindow:);
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
[inv setTarget:[[VLCMain sharedInstance] voutController]];
int i_full = va_arg(args, int);
SEL sel = @selector(setFullscreen:forWindow:);
- NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[VLCMain sharedInstance] methodSignatureForSelector:sel]];
- [inv setTarget:[VLCMain sharedInstance]];
+ NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
+ [inv setTarget:[[VLCMain sharedInstance] voutController]];
[inv setSelector:sel];
[inv setArgument:&i_full atIndex:2]; // starting at 2!
[inv setArgument:&p_wnd atIndex:3];
* Run: main loop
*****************************************************************************/
static NSLock * o_appLock = nil; // controls access to f_appExit
+static NSLock * o_plItemChangedLock = nil;
static void Run(intf_thread_t *p_intf)
{
[VLCApplication sharedApplication];
o_appLock = [[NSLock alloc] init];
+ o_plItemChangedLock = [[NSLock alloc] init];
[[VLCMain sharedInstance] setIntf: p_intf];
[NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
[NSApp run];
[[VLCMain sharedInstance] applicationWillTerminate:nil];
+ [o_plItemChangedLock release];
[o_appLock release];
[o_pool release];
vlc_value_t oldval, vlc_value_t new_val, void *param)
{
NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
- [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:NO];
+
+ /* Due to constraints within NSAttributedString's main loop runtime handling
+ * and other issues, we need to wait for -PlaylistItemChanged to finish and
+ * then -informInputChanged on this non-main thread. */
+ [o_plItemChangedLock lock];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:YES];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(informInputChanged) withObject:nil waitUntilDone:YES];
+ [o_plItemChangedLock unlock];
[o_pool release];
return VLC_SUCCESS;
_o_sharedMainInstance = [super init];
p_intf = NULL;
- p_current_input = NULL;
+ p_current_input = p_input_changed = NULL;
o_msg_lock = [[NSLock alloc] init];
o_msg_arr = [[NSMutableArray arrayWithCapacity: 600] retain];
b_nativeFullscreenMode = var_InheritBool(p_intf, "macosx-nativefullscreenmode");
#endif
- /* recover stored audio device, if set
- * in case it was unplugged in the meantime, auhal will fall back on the default */
- int i_value = config_GetInt(p_intf, "macosx-audio-device");
- if (i_value > 0)
- var_SetInteger(pl_Get(VLCIntf), "audio-device", i_value);
-
if (config_GetInt(VLCIntf, "macosx-icon-change")) {
/* After day 354 of the year, the usual VLC cone is replaced by another cone
* wearing a Father Xmas hat.
[NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
}
+ /* save current video and audio profiles */
+ [[VLCVideoEffects sharedInstance] saveCurrentProfile];
+ [[VLCAudioEffects sharedInstance] saveCurrentProfile];
+
/* Save some interface state in configuration, at module quit */
config_PutInt(p_intf, "random", var_GetBool(p_playlist, "random"));
config_PutInt(p_intf, "loop", var_GetBool(p_playlist, "loop"));
/* remove global observer watching for vout device changes correctly */
[[NSNotificationCenter defaultCenter] removeObserver: self];
+ // release before o_info!
+ [o_vout_controller release];
+ o_vout_controller = nil;
+
/* release some other objects here, because it isn't sure whether dealloc
* will be called later on */
if (o_sprefs)
/* write cached user defaults to disk */
[[NSUserDefaults standardUserDefaults] synchronize];
- [o_mainmenu release];
- [o_vout_controller release];
- o_vout_controller = nil;
+ [o_mainmenu release];
libvlc_Quit(p_intf->p_libvlc);
int keyRepeat = (keyFlags & 0x1);
if (keyCode == NX_KEYTYPE_PLAY && keyState == 0)
- [[VLCCoreInteraction sharedInstance] play];
+ [[VLCCoreInteraction sharedInstance] playOrPause];
if ((keyCode == NX_KEYTYPE_FAST || keyCode == NX_KEYTYPE_NEXT) && !b_mediakeyJustJumped) {
if (keyState == 0 && keyRepeat == 0)
[[VLCCoreInteraction sharedInstance] backward];
break;
case kRemoteButtonVolume_Plus_Hold:
- if (p_intf)
- var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_UP);
+ [[VLCCoreInteraction sharedInstance] volumeUp];
break;
case kRemoteButtonVolume_Minus_Hold:
- if (p_intf)
- var_SetInteger(p_intf->p_libvlc, "key-action", ACTIONID_VOL_DOWN);
+ [[VLCCoreInteraction sharedInstance] volumeDown];
break;
}
if (b_remote_button_hold) {
[[VLCCoreInteraction sharedInstance] toggleFullscreen];
break;
case k2009RemoteButtonPlay:
- [[VLCCoreInteraction sharedInstance] play];
+ [[VLCCoreInteraction sharedInstance] playOrPause];
break;
case kRemoteButtonPlay:
if (count >= 2)
[[VLCCoreInteraction sharedInstance] toggleFullscreen];
else
- [[VLCCoreInteraction sharedInstance] play];
+ [[VLCCoreInteraction sharedInstance] playOrPause];
break;
case kRemoteButtonVolume_Plus:
if (config_GetInt(VLCIntf, "macosx-appleremote-sysvol"))
case NSBackspaceCharacter:
case NSUpArrowFunctionKey:
case NSDownArrowFunctionKey:
- case NSRightArrowFunctionKey:
- case NSLeftArrowFunctionKey:
case NSEnterCharacter:
case NSCarriageReturnCharacter:
return NO;
}
if (key == 0x0020) { // space key
- [[VLCCoreInteraction sharedInstance] play];
+ [[VLCCoreInteraction sharedInstance] playOrPause];
return YES;
}
#pragma mark -
#pragma mark Interface updaters
-- (void)setFullscreen:(int)i_full forWindow:(vout_window_t *)p_wnd
-{
- if (!p_intf || (!b_nativeFullscreenMode && !p_wnd))
- return;
- playlist_t * p_playlist = pl_Get(p_intf);
- BOOL b_fullscreen = i_full;
-
- if (!var_GetBool(p_playlist, "fullscreen") != !b_fullscreen) {
- var_SetBool(p_playlist, "fullscreen", b_fullscreen);
- }
-
- if (b_nativeFullscreenMode) {
- // this is called twice in certain situations, so only toogle if we really need to
- if ((b_fullscreen && !([NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen)) ||
- (!b_fullscreen && ([NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen)))
- [o_mainwindow toggleFullScreen: self];
-
- if (b_fullscreen)
- [NSApp setPresentationOptions:(NSApplicationPresentationFullScreen | NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
- else
- [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
- } else {
- assert(p_wnd);
-
- if (b_fullscreen) {
- input_thread_t * p_input = pl_CurrentInput(p_intf);
- if (p_input != NULL && [self activeVideoPlayback]) {
- // activate app, as method can also be triggered from outside the app (prevents nasty window layout)
- [NSApp activateIgnoringOtherApps:YES];
- [o_vout_controller updateWindow:p_wnd withSelector:@selector(enterFullscreen)];
-
- }
- if (p_input)
- vlc_object_release(p_input);
- } else {
- // leaving fullscreen is always allowed
- [o_vout_controller updateWindow:p_wnd withSelector:@selector(leaveFullscreen)];
- }
- }
-}
- (void)PlaylistItemChanged
{
if (p_current_input && (p_current_input->b_dead || !vlc_object_alive(p_current_input))) {
var_DelCallback(p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance]);
- vlc_object_release(p_current_input);
+ p_input_changed = p_current_input;
p_current_input = NULL;
[o_mainmenu setRateControlsEnabled: NO];
[o_mainmenu setRateControlsEnabled: YES];
if ([self activeVideoPlayback] && [[o_mainwindow videoView] isHidden])
[o_mainwindow performSelectorOnMainThread:@selector(togglePlaylist:) withObject: nil waitUntilDone:NO];
+ p_input_changed = vlc_object_hold(p_current_input);
}
}
[self updateMainMenu];
}
+- (void)informInputChanged
+{
+ if (p_input_changed) {
+ [[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed];
+ vlc_object_release(p_input_changed);
+ p_input_changed = NULL;
+ }
+}
+
- (void)updateMainMenu
{
[o_mainmenu setupMenus];
if (p_input) {
int state = var_GetInteger(p_input, "state");
if (state == PLAYING_S) {
+ /* Declare user activity.
+ This wakes the display if it is off, and postpones display sleep according to the users system preferences
+ Available from 10.7.3 */
+#ifdef MAC_OS_X_VERSION_10_7
+ if ([self activeVideoPlayback] && IOPMAssertionDeclareUserActivity)
+ {
+ CFStringRef reasonForActivity = CFStringCreateWithCString(kCFAllocatorDefault, _("VLC media playback"), kCFStringEncodingUTF8);
+ IOPMAssertionDeclareUserActivity(reasonForActivity,
+ kIOPMUserActiveLocal,
+ &userActivityAssertionID);
+ CFRelease(reasonForActivity);
+ }
+#endif
+
/* prevent the system from sleeping */
if (systemSleepAssertionID > 0) {
msg_Dbg(VLCIntf, "releasing old sleep blocker (%i)" , systemSleepAssertionID);
#pragma mark -
#pragma mark Window updater
-- (void)setWindowLevel:(NSNumber*)state
-{
- if (var_InheritBool(p_intf, "video-wallpaper") || [[[[VLCMainWindow sharedInstance] videoView] window] level] < NSNormalWindowLevel)
- return;
- if ([state unsignedIntValue] & VOUT_WINDOW_STATE_ABOVE)
- [[[[VLCMainWindow sharedInstance] videoView] window] setLevel: NSStatusWindowLevel];
- else
- [[[[VLCMainWindow sharedInstance] videoView] window] setLevel: NSNormalWindowLevel];
-}
- (void)setActiveVideoPlayback:(BOOL)b_value
{