]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/intf.m
macosx: move fullscreen logic to VLCVoutController and remove now unneeded helper...
[vlc] / modules / gui / macosx / intf.m
index 9727c95a9095eb3952b3e3d61356c352682b4843..fcb005ccc479f87fe0d26d85c49aa82b664efb21 100644 (file)
@@ -1,13 +1,14 @@
 /*****************************************************************************
  * 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 */
@@ -136,7 +141,6 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
         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];
@@ -168,8 +172,8 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
         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];
@@ -190,7 +194,20 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
         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:
@@ -200,7 +217,7 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
             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]];
@@ -219,8 +236,8 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
             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];
@@ -249,6 +266,7 @@ void WindowClose(vout_window_t *p_wnd)
  * 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)
 {
@@ -256,12 +274,14 @@ 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];
 
@@ -378,7 +398,14 @@ static int PLItemChanged(vlc_object_t *p_this, const char *psz_var,
                          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;
@@ -579,7 +606,7 @@ static VLCMain *_o_sharedMainInstance = nil;
         _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];
@@ -685,12 +712,6 @@ static VLCMain *_o_sharedMainInstance = nil;
         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.
@@ -796,6 +817,10 @@ static VLCMain *_o_sharedMainInstance = nil;
         [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"));
@@ -832,6 +857,10 @@ static VLCMain *_o_sharedMainInstance = nil;
     /* 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)
@@ -868,10 +897,8 @@ static VLCMain *_o_sharedMainInstance = nil;
     /* 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);
 
@@ -905,7 +932,7 @@ static VLCMain *_o_sharedMainInstance = nil;
         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)
@@ -1026,12 +1053,10 @@ static VLCMain *_o_sharedMainInstance = nil;
                 [[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) {
@@ -1053,13 +1078,13 @@ static VLCMain *_o_sharedMainInstance = nil;
             [[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"))
@@ -1160,8 +1185,6 @@ static VLCMain *_o_sharedMainInstance = nil;
                 case NSBackspaceCharacter:
                 case NSUpArrowFunctionKey:
                 case NSDownArrowFunctionKey:
-                case NSRightArrowFunctionKey:
-                case NSLeftArrowFunctionKey:
                 case NSEnterCharacter:
                 case NSCarriageReturnCharacter:
                     return NO;
@@ -1169,7 +1192,7 @@ static VLCMain *_o_sharedMainInstance = nil;
         }
 
         if (key == 0x0020) { // space key
-            [[VLCCoreInteraction sharedInstance] play];
+            [[VLCCoreInteraction sharedInstance] playOrPause];
             return YES;
         }
 
@@ -1230,52 +1253,12 @@ static VLCMain *_o_sharedMainInstance = nil;
 
 #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];
@@ -1289,6 +1272,7 @@ static VLCMain *_o_sharedMainInstance = nil;
             [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);
         }
     }
 
@@ -1298,6 +1282,15 @@ static VLCMain *_o_sharedMainInstance = nil;
     [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];
@@ -1367,6 +1360,20 @@ static VLCMain *_o_sharedMainInstance = nil;
     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);
@@ -1450,16 +1457,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 #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
 {