macosx: Rename to VLCInputManager
authorDavid Fuhrmann <dfuhrmann@videolan.org>
Mon, 8 Aug 2016 15:55:19 +0000 (17:55 +0200)
committerDavid Fuhrmann <dfuhrmann@videolan.org>
Mon, 8 Aug 2016 16:47:29 +0000 (18:47 +0200)
extras/package/macosx/vlc.xcodeproj/project.pbxproj
modules/gui/macosx/CoreInteraction.m
modules/gui/macosx/InputManager.h [deleted file]
modules/gui/macosx/InputManager.m [deleted file]
modules/gui/macosx/Makefile.am
modules/gui/macosx/VLCInputManager.h [new file with mode: 0644]
modules/gui/macosx/VLCInputManager.m [new file with mode: 0644]
modules/gui/macosx/intf.m

index f53f1b7..fba1faf 100644 (file)
                7DE88F291831396A00CD9DA2 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/PlaylistAccessoryView.xib; sourceTree = "<group>"; };
                7DF0435E1972E26A0022B534 /* AddonListDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AddonListDataSource.h; path = ../../../modules/gui/macosx/AddonListDataSource.h; sourceTree = SOURCE_ROOT; };
                7DF0435F1972E26A0022B534 /* AddonListDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AddonListDataSource.m; path = ../../../modules/gui/macosx/AddonListDataSource.m; sourceTree = SOURCE_ROOT; };
-               7DF812ED1B555A340052293C /* InputManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InputManager.h; path = ../../../modules/gui/macosx/InputManager.h; sourceTree = "<group>"; };
-               7DF812EE1B555A340052293C /* InputManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = InputManager.m; path = ../../../modules/gui/macosx/InputManager.m; sourceTree = "<group>"; };
+               7DF812ED1B555A340052293C /* VLCInputManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCInputManager.h; path = ../../../modules/gui/macosx/VLCInputManager.h; sourceTree = "<group>"; };
+               7DF812EE1B555A340052293C /* VLCInputManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = VLCInputManager.m; path = ../../../modules/gui/macosx/VLCInputManager.m; sourceTree = "<group>"; };
                7DF812EF1B555C8E0052293C /* KeyboardBacklight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = KeyboardBacklight.h; path = ../../../modules/gui/macosx/KeyboardBacklight.h; sourceTree = "<group>"; };
                7DF812F01B555C8E0052293C /* KeyboardBacklight.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = KeyboardBacklight.m; path = ../../../modules/gui/macosx/KeyboardBacklight.m; sourceTree = "<group>"; };
                7DF812F11B5599E40052293C /* PLItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PLItem.h; path = ../../../modules/gui/macosx/PLItem.h; sourceTree = "<group>"; };
                                2AEF857609A5FEC900130822 /* fspanel.h */,
                                2AEF857709A5FEC900130822 /* fspanel.m */,
                                7D871D391B5E684D000B56C0 /* helpers.h */,
-                               7DF812ED1B555A340052293C /* InputManager.h */,
-                               7DF812EE1B555A340052293C /* InputManager.m */,
+                               7DF812ED1B555A340052293C /* VLCInputManager.h */,
+                               7DF812EE1B555A340052293C /* VLCInputManager.m */,
                                7D871D371B5E6844000B56C0 /* intf-prefs.h */,
                                7D871D381B5E6844000B56C0 /* intf-prefs.m */,
                                8ED6C27C03E2EB1C0059A3A7 /* intf.h */,
index b17138c..78e8946 100644 (file)
@@ -39,7 +39,7 @@
 #include <vlc_plugin.h>
 #import "SPMediaKeyTap.h"
 #import "AppleRemote.h"
-#import "InputManager.h"
+#import "VLCInputManager.h"
 
 static int BossCallback(vlc_object_t *p_this, const char *psz_var,
                         vlc_value_t oldval, vlc_value_t new_val, void *param)
diff --git a/modules/gui/macosx/InputManager.h b/modules/gui/macosx/InputManager.h
deleted file mode 100644 (file)
index 516240b..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*****************************************************************************
- * InputManager.h: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2015 VLC authors and VideoLAN
- * $Id$
- *
- * 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 <Cocoa/Cocoa.h>
-
-#include <vlc_common.h>
-#import <vlc_interface.h>
-
-#import <IOKit/pwr_mgt/IOPMLib.h>           /* for sleep prevention */
-
-
-@class VLCMain;
-
-@interface VLCInputManager : NSObject
-
-- (id)initWithMain:(VLCMain *)o_mainObj;
-
-- (void)inputThreadChanged;
-
-- (void)playbackStatusUpdated;
-
-- (void)resumeItunesPlayback:(id)sender;
-
-- (BOOL)hasInput;
-
-@end
diff --git a/modules/gui/macosx/InputManager.m b/modules/gui/macosx/InputManager.m
deleted file mode 100644 (file)
index fed2268..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-/*****************************************************************************
- * InputManager.m: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2015 VLC authors and VideoLAN
- * $Id$
- *
- * 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 "InputManager.h"
-
-#import "CoreInteraction.h"
-#import "CompatibilityFixes.h"
-#import "ExtensionsManager.h"
-#import "intf.h"
-#import "MainMenu.h"
-#import "VLCMainWindow.h"
-#import "VLCPlaylist.h"
-#import "VLCPlaylistInfo.h"
-#import "VLCResumeDialogController.h"
-#import "VLCTrackSynchronizationWindowController.h"
-#import "VideoView.h"
-
-#import "iTunes.h"
-#import "Spotify.h"
-
-#pragma mark Callbacks
-
-static int InputThreadChanged(vlc_object_t *p_this, const char *psz_var,
-                              vlc_value_t oldval, vlc_value_t new_val, void *param)
-{
-    @autoreleasepool {
-        VLCInputManager *inputManager = (__bridge VLCInputManager *)param;
-        [inputManager performSelectorOnMainThread:@selector(inputThreadChanged) withObject:nil waitUntilDone:NO];
-    }
-
-    return VLC_SUCCESS;
-}
-
-
-static int InputEvent(vlc_object_t *p_this, const char *psz_var,
-                      vlc_value_t oldval, vlc_value_t new_val, void *param)
-{
-    @autoreleasepool {
-        VLCInputManager *inputManager = (__bridge VLCInputManager *)param;
-
-        switch (new_val.i_int) {
-            case INPUT_EVENT_STATE:
-                [inputManager performSelectorOnMainThread:@selector(playbackStatusUpdated) withObject: nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_RATE:
-                [[[VLCMain sharedInstance] mainMenu] performSelectorOnMainThread:@selector(updatePlaybackRate) withObject: nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_POSITION:
-                [[[VLCMain sharedInstance] mainWindow] performSelectorOnMainThread:@selector(updateTimeSlider) withObject: nil waitUntilDone:NO];
-                [[[VLCMain sharedInstance] statusBarIcon] performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_TITLE:
-            case INPUT_EVENT_CHAPTER:
-                [inputManager performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_CACHE:
-                [inputManager performSelectorOnMainThread:@selector(updateMainWindow) withObject:nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_STATISTICS:
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [[[VLCMain sharedInstance] currentMediaInfoPanel] updateStatistics];
-                });
-                break;
-            case INPUT_EVENT_ES:
-                break;
-            case INPUT_EVENT_TELETEXT:
-                break;
-            case INPUT_EVENT_AOUT:
-                break;
-            case INPUT_EVENT_VOUT:
-                break;
-            case INPUT_EVENT_ITEM_META:
-            case INPUT_EVENT_ITEM_INFO:
-                [inputManager performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
-                [inputManager performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
-                [inputManager performSelectorOnMainThread:@selector(updateMetaAndInfo) withObject: nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_BOOKMARK:
-                break;
-            case INPUT_EVENT_RECORD:
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [[[VLCMain sharedInstance] mainMenu] updateRecordState: var_InheritBool(p_this, "record")];
-                });
-                break;
-            case INPUT_EVENT_PROGRAM:
-                [inputManager performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
-                break;
-            case INPUT_EVENT_ITEM_EPG:
-                break;
-            case INPUT_EVENT_SIGNAL:
-                break;
-
-            case INPUT_EVENT_ITEM_NAME:
-                [inputManager performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
-                break;
-
-            case INPUT_EVENT_AUDIO_DELAY:
-            case INPUT_EVENT_SUBTITLE_DELAY:
-                [inputManager performSelectorOnMainThread:@selector(updateDelays) withObject:nil waitUntilDone:NO];
-                break;
-
-            case INPUT_EVENT_DEAD:
-                [inputManager performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
-                [[[VLCMain sharedInstance] mainWindow] performSelectorOnMainThread:@selector(updateTimeSlider) withObject:nil waitUntilDone:NO];
-                break;
-
-            default:
-                break;
-        }
-
-        return VLC_SUCCESS;
-    }
-}
-
-#pragma mark -
-#pragma mark InputManager implementation
-
-@interface VLCInputManager()
-{
-    __weak VLCMain *o_main;
-
-    input_thread_t *p_current_input;
-    dispatch_queue_t informInputChangedQueue;
-
-    /* sleep management */
-    IOPMAssertionID systemSleepAssertionID;
-    IOPMAssertionID userActivityAssertionID;
-
-    /* iTunes/Spotify play/pause support */
-    BOOL b_has_itunes_paused;
-    BOOL b_has_spotify_paused;
-    NSTimer *o_itunes_play_timer;
-}
-@end
-
-@implementation VLCInputManager
-
-- (id)initWithMain:(VLCMain *)o_mainObj
-{
-    self = [super init];
-    if(self) {
-        msg_Dbg(getIntf(), "Initializing input manager");
-
-        o_main = o_mainObj;
-        var_AddCallback(pl_Get(getIntf()), "input-current", InputThreadChanged, (__bridge void *)self);
-
-        informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
-
-    }
-    return self;
-}
-
-- (void)dealloc
-{
-    msg_Dbg(getIntf(), "Deinitializing input manager");
-    if (p_current_input) {
-        /* continue playback where you left off */
-        [[o_main playlist] storePlaybackPositionForItem:p_current_input];
-
-        var_DelCallback(p_current_input, "intf-event", InputEvent, (__bridge void *)self);
-        vlc_object_release(p_current_input);
-        p_current_input = NULL;
-    }
-
-    var_DelCallback(pl_Get(getIntf()), "input-current", InputThreadChanged, (__bridge void *)self);
-
-#if !OS_OBJECT_USE_OBJC
-    dispatch_release(informInputChangedQueue);
-#endif
-}
-
-- (void)inputThreadChanged
-{
-    if (p_current_input) {
-        var_DelCallback(p_current_input, "intf-event", InputEvent, (__bridge void *)self);
-        vlc_object_release(p_current_input);
-        p_current_input = NULL;
-
-        [[o_main mainMenu] setRateControlsEnabled: NO];
-
-        [[NSNotificationCenter defaultCenter] postNotificationName:VLCInputChangedNotification
-                                                            object:nil];
-    }
-
-    // Cancel pending resume dialogs
-    [[[VLCMain sharedInstance] resumeDialog] cancel];
-
-    input_thread_t *p_input_changed = NULL;
-
-    // object is hold here and released then it is dead
-    p_current_input = playlist_CurrentInput(pl_Get(getIntf()));
-    if (p_current_input) {
-        var_AddCallback(p_current_input, "intf-event", InputEvent, (__bridge void *)self);
-        [self playbackStatusUpdated];
-        [[o_main mainMenu] setRateControlsEnabled: YES];
-
-        if ([o_main activeVideoPlayback] && [[[o_main mainWindow] videoView] isHidden]) {
-            [[o_main mainWindow] changePlaylistState: psPlaylistItemChangedEvent];
-        }
-
-        p_input_changed = vlc_object_hold(p_current_input);
-
-        [[o_main playlist] currentlyPlayingItemChanged];
-
-        [[o_main playlist] continuePlaybackWhereYouLeftOff:p_current_input];
-
-        [[NSNotificationCenter defaultCenter] postNotificationName:VLCInputChangedNotification
-                                                            object:nil];
-    }
-
-    [self updateMetaAndInfo];
-
-    [self updateMainWindow];
-    [self updateDelays];
-    [self updateMainMenu];
-
-    /*
-     * Due to constraints within NSAttributedString's main loop runtime handling
-     * and other issues, we need to inform the extension manager on a separate thread.
-     * The serial queue ensures that changed inputs are propagated in the same order as they arrive.
-     */
-    dispatch_async(informInputChangedQueue, ^{
-        [[o_main extensionsManager] inputChanged:p_input_changed];
-        if (p_input_changed)
-            vlc_object_release(p_input_changed);
-    });
-}
-
-- (void)playbackStatusUpdated
-{
-    intf_thread_t *p_intf = getIntf();
-    int state = -1;
-    if (p_current_input) {
-        state = var_GetInteger(p_current_input, "state");
-    }
-
-    int i_control_itunes = var_InheritInteger(p_intf, "macosx-control-itunes");
-    // cancel itunes timer if next item starts playing
-    if (state > -1 && state != END_S && i_control_itunes > 0) {
-        if (o_itunes_play_timer) {
-            [o_itunes_play_timer invalidate];
-            o_itunes_play_timer = nil;
-        }
-    }
-
-    if (state == PLAYING_S) {
-        if (i_control_itunes > 0) {
-            // pause iTunes
-            if (!b_has_itunes_paused) {
-                iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
-                if (iTunesApp && [iTunesApp isRunning]) {
-                    if ([iTunesApp playerState] == iTunesEPlSPlaying) {
-                        msg_Dbg(p_intf, "pausing iTunes");
-                        [iTunesApp pause];
-                        b_has_itunes_paused = YES;
-                    }
-                }
-            }
-
-            // pause Spotify
-            if (!b_has_spotify_paused) {
-                SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
-
-                if (spotifyApp) {
-                    if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
-                        if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePlaying) {
-                            msg_Dbg(p_intf, "pausing Spotify");
-                            [spotifyApp pause];
-                            b_has_spotify_paused = YES;
-                        }
-                    }
-                }
-            }
-        }
-
-        BOOL shouldDisableScreensaver = var_InheritBool(p_intf, "disable-screensaver");
-
-        /* 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 */
-        if ([o_main activeVideoPlayback] && &IOPMAssertionDeclareUserActivity && shouldDisableScreensaver)
-        {
-            CFStringRef reasonForActivity = CFStringCreateWithCString(kCFAllocatorDefault, _("VLC media playback"), kCFStringEncodingUTF8);
-            IOReturn success = IOPMAssertionDeclareUserActivity(reasonForActivity,
-                                             kIOPMUserActiveLocal,
-                                             &userActivityAssertionID);
-            CFRelease(reasonForActivity);
-
-            if (success != kIOReturnSuccess)
-                msg_Warn(getIntf(), "failed to declare user activity");
-
-        }
-
-        /* prevent the system from sleeping */
-        if (systemSleepAssertionID > 0) {
-            msg_Dbg(getIntf(), "releasing old sleep blocker (%i)" , systemSleepAssertionID);
-            IOPMAssertionRelease(systemSleepAssertionID);
-        }
-
-        IOReturn success;
-        /* work-around a bug in 10.7.4 and 10.7.5, so check for 10.7.x < 10.7.4 and 10.8 */
-        if (NSAppKitVersionNumber < 1115.2) {
-            /* fall-back on the 10.5 mode, which also works on 10.7.4 and 10.7.5 */
-            if ([o_main activeVideoPlayback] && shouldDisableScreensaver)
-                success = IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &systemSleepAssertionID);
-            else
-                success = IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &systemSleepAssertionID);
-        } else {
-            CFStringRef reasonForActivity = CFStringCreateWithCString(kCFAllocatorDefault, _("VLC media playback"), kCFStringEncodingUTF8);
-            if ([o_main activeVideoPlayback] && shouldDisableScreensaver)
-                success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &systemSleepAssertionID);
-            else
-                success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reasonForActivity, &systemSleepAssertionID);
-            CFRelease(reasonForActivity);
-        }
-
-        if (success == kIOReturnSuccess)
-            msg_Dbg(getIntf(), "prevented sleep through IOKit (%i)", systemSleepAssertionID);
-        else
-            msg_Warn(getIntf(), "failed to prevent system sleep through IOKit");
-
-        [[o_main mainMenu] setPause];
-        [[o_main mainWindow] setPause];
-    } else {
-        [[o_main mainMenu] setSubmenusEnabled: FALSE];
-        [[o_main mainMenu] setPlay];
-        [[o_main mainWindow] setPlay];
-
-        /* allow the system to sleep again */
-        if (systemSleepAssertionID > 0) {
-            msg_Dbg(getIntf(), "releasing sleep blocker (%i)" , systemSleepAssertionID);
-            IOPMAssertionRelease(systemSleepAssertionID);
-        }
-
-        if (state == END_S || state == -1) {
-            /* continue playback where you left off */
-            if (p_current_input)
-                [[o_main playlist] storePlaybackPositionForItem:p_current_input];
-
-            if (i_control_itunes > 0) {
-                if (o_itunes_play_timer) {
-                    [o_itunes_play_timer invalidate];
-                }
-                o_itunes_play_timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
-                                                                       target: self
-                                                                     selector: @selector(resumeItunesPlayback:)
-                                                                     userInfo: nil
-                                                                      repeats: NO];
-            }
-        }
-    }
-
-    [self updateMainWindow];
-    [self sendDistributedNotificationWithUpdatedPlaybackStatus];
-}
-
-
-- (void)resumeItunesPlayback:(id)sender
-{
-    intf_thread_t *p_intf = getIntf();
-    if (var_InheritInteger(p_intf, "macosx-control-itunes") > 1) {
-        if (b_has_itunes_paused) {
-            iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
-            if (iTunesApp && [iTunesApp isRunning]) {
-                if ([iTunesApp playerState] == iTunesEPlSPaused) {
-                    msg_Dbg(p_intf, "unpausing iTunes");
-                    [iTunesApp playpause];
-                }
-            }
-        }
-
-        if (b_has_spotify_paused) {
-            SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
-            if (spotifyApp) {
-                if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
-                    if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePaused) {
-                        msg_Dbg(p_intf, "unpausing Spotify");
-                        [spotifyApp play];
-                    }
-                }
-            }
-        }
-    }
-
-    b_has_itunes_paused = NO;
-    b_has_spotify_paused = NO;
-    o_itunes_play_timer = nil;
-}
-
-- (void)updateMetaAndInfo
-{
-    if (!p_current_input) {
-        [[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:nil];
-        return;
-    }
-
-    input_item_t *p_input_item = input_GetItem(p_current_input);
-
-    [[[o_main playlist] model] updateItem:p_input_item];
-    [[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:p_input_item];
-}
-
-- (void)updateMainWindow
-{
-    [[o_main mainWindow] updateWindow];
-}
-
-- (void)updateName
-{
-    [[o_main mainWindow] updateName];
-}
-
-- (void)updateDelays
-{
-    [[[VLCMain sharedInstance] trackSyncPanel] updateValues];
-}
-
-- (void)updateMainMenu
-{
-    [[o_main mainMenu] setupMenus];
-    [[o_main mainMenu] updatePlaybackRate];
-    [[VLCCoreInteraction sharedInstance] resetAtoB];
-}
-
-- (void)sendDistributedNotificationWithUpdatedPlaybackStatus
-{
-    [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"VLCPlayerStateDidChange"
-                                                                   object:nil
-                                                                 userInfo:nil
-                                                       deliverImmediately:YES];
-}
-
-- (BOOL)hasInput
-{
-    return p_current_input != NULL;
-}
-
-@end
index 9ca84b4..a7eaaaa 100644 (file)
@@ -38,7 +38,6 @@ libmacosx_plugin_la_SOURCES = \
        HelpWindowController.h HelpWindowController.m \
        intf-prefs.h intf-prefs.m \
        intf.h intf.m \
-       InputManager.h InputManager.m \
        iTunes.h \
        KeyboardBacklight.h KeyboardBacklight.m \
        macosx.m \
@@ -79,6 +78,7 @@ libmacosx_plugin_la_SOURCES = \
        VLCHUDCheckboxCell.h VLCHUDCheckboxCell.m \
        VLCHUDRadiobuttonCell.h VLCHUDRadiobuttonCell.m \
        VLCHUDTextFieldCell.h VLCHUDTextFieldCell.m \
+       VLCInputManager.h VLCInputManager.m \
        VLCMainWindow.h VLCMainWindow.m \
        VLCRendererDiscovery.h VLCRendererDiscovery.m \
        VLCRendererItem.h VLCRendererItem.m \
diff --git a/modules/gui/macosx/VLCInputManager.h b/modules/gui/macosx/VLCInputManager.h
new file mode 100644 (file)
index 0000000..791463c
--- /dev/null
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * VLCInputManager.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * 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 <Cocoa/Cocoa.h>
+
+#include <vlc_common.h>
+#import <vlc_interface.h>
+
+#import <IOKit/pwr_mgt/IOPMLib.h>           /* for sleep prevention */
+
+
+@class VLCMain;
+
+@interface VLCInputManager : NSObject
+
+- (id)initWithMain:(VLCMain *)o_mainObj;
+
+- (void)inputThreadChanged;
+
+- (void)playbackStatusUpdated;
+
+- (void)resumeItunesPlayback:(id)sender;
+
+- (BOOL)hasInput;
+
+@end
diff --git a/modules/gui/macosx/VLCInputManager.m b/modules/gui/macosx/VLCInputManager.m
new file mode 100644 (file)
index 0000000..b6c7220
--- /dev/null
@@ -0,0 +1,456 @@
+/*****************************************************************************
+ * VLCInputManager.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * 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 "VLCInputManager.h"
+
+#import "CoreInteraction.h"
+#import "CompatibilityFixes.h"
+#import "ExtensionsManager.h"
+#import "intf.h"
+#import "MainMenu.h"
+#import "VLCMainWindow.h"
+#import "VLCPlaylist.h"
+#import "VLCPlaylistInfo.h"
+#import "VLCResumeDialogController.h"
+#import "VLCTrackSynchronizationWindowController.h"
+#import "VideoView.h"
+
+#import "iTunes.h"
+#import "Spotify.h"
+
+#pragma mark Callbacks
+
+static int InputThreadChanged(vlc_object_t *p_this, const char *psz_var,
+                              vlc_value_t oldval, vlc_value_t new_val, void *param)
+{
+    @autoreleasepool {
+        VLCInputManager *inputManager = (__bridge VLCInputManager *)param;
+        [inputManager performSelectorOnMainThread:@selector(inputThreadChanged) withObject:nil waitUntilDone:NO];
+    }
+
+    return VLC_SUCCESS;
+}
+
+
+static int InputEvent(vlc_object_t *p_this, const char *psz_var,
+                      vlc_value_t oldval, vlc_value_t new_val, void *param)
+{
+    @autoreleasepool {
+        VLCInputManager *inputManager = (__bridge VLCInputManager *)param;
+
+        switch (new_val.i_int) {
+            case INPUT_EVENT_STATE:
+                [inputManager performSelectorOnMainThread:@selector(playbackStatusUpdated) withObject: nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_RATE:
+                [[[VLCMain sharedInstance] mainMenu] performSelectorOnMainThread:@selector(updatePlaybackRate) withObject: nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_POSITION:
+                [[[VLCMain sharedInstance] mainWindow] performSelectorOnMainThread:@selector(updateTimeSlider) withObject: nil waitUntilDone:NO];
+                [[[VLCMain sharedInstance] statusBarIcon] performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_TITLE:
+            case INPUT_EVENT_CHAPTER:
+                [inputManager performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_CACHE:
+                [inputManager performSelectorOnMainThread:@selector(updateMainWindow) withObject:nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_STATISTICS:
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [[[VLCMain sharedInstance] currentMediaInfoPanel] updateStatistics];
+                });
+                break;
+            case INPUT_EVENT_ES:
+                break;
+            case INPUT_EVENT_TELETEXT:
+                break;
+            case INPUT_EVENT_AOUT:
+                break;
+            case INPUT_EVENT_VOUT:
+                break;
+            case INPUT_EVENT_ITEM_META:
+            case INPUT_EVENT_ITEM_INFO:
+                [inputManager performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
+                [inputManager performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+                [inputManager performSelectorOnMainThread:@selector(updateMetaAndInfo) withObject: nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_BOOKMARK:
+                break;
+            case INPUT_EVENT_RECORD:
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [[[VLCMain sharedInstance] mainMenu] updateRecordState: var_InheritBool(p_this, "record")];
+                });
+                break;
+            case INPUT_EVENT_PROGRAM:
+                [inputManager performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
+                break;
+            case INPUT_EVENT_ITEM_EPG:
+                break;
+            case INPUT_EVENT_SIGNAL:
+                break;
+
+            case INPUT_EVENT_ITEM_NAME:
+                [inputManager performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+                break;
+
+            case INPUT_EVENT_AUDIO_DELAY:
+            case INPUT_EVENT_SUBTITLE_DELAY:
+                [inputManager performSelectorOnMainThread:@selector(updateDelays) withObject:nil waitUntilDone:NO];
+                break;
+
+            case INPUT_EVENT_DEAD:
+                [inputManager performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+                [[[VLCMain sharedInstance] mainWindow] performSelectorOnMainThread:@selector(updateTimeSlider) withObject:nil waitUntilDone:NO];
+                break;
+
+            default:
+                break;
+        }
+
+        return VLC_SUCCESS;
+    }
+}
+
+#pragma mark -
+#pragma mark InputManager implementation
+
+@interface VLCInputManager()
+{
+    __weak VLCMain *o_main;
+
+    input_thread_t *p_current_input;
+    dispatch_queue_t informInputChangedQueue;
+
+    /* sleep management */
+    IOPMAssertionID systemSleepAssertionID;
+    IOPMAssertionID userActivityAssertionID;
+
+    /* iTunes/Spotify play/pause support */
+    BOOL b_has_itunes_paused;
+    BOOL b_has_spotify_paused;
+    NSTimer *o_itunes_play_timer;
+}
+@end
+
+@implementation VLCInputManager
+
+- (id)initWithMain:(VLCMain *)o_mainObj
+{
+    self = [super init];
+    if(self) {
+        msg_Dbg(getIntf(), "Initializing input manager");
+
+        o_main = o_mainObj;
+        var_AddCallback(pl_Get(getIntf()), "input-current", InputThreadChanged, (__bridge void *)self);
+
+        informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
+
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    msg_Dbg(getIntf(), "Deinitializing input manager");
+    if (p_current_input) {
+        /* continue playback where you left off */
+        [[o_main playlist] storePlaybackPositionForItem:p_current_input];
+
+        var_DelCallback(p_current_input, "intf-event", InputEvent, (__bridge void *)self);
+        vlc_object_release(p_current_input);
+        p_current_input = NULL;
+    }
+
+    var_DelCallback(pl_Get(getIntf()), "input-current", InputThreadChanged, (__bridge void *)self);
+
+#if !OS_OBJECT_USE_OBJC
+    dispatch_release(informInputChangedQueue);
+#endif
+}
+
+- (void)inputThreadChanged
+{
+    if (p_current_input) {
+        var_DelCallback(p_current_input, "intf-event", InputEvent, (__bridge void *)self);
+        vlc_object_release(p_current_input);
+        p_current_input = NULL;
+
+        [[o_main mainMenu] setRateControlsEnabled: NO];
+
+        [[NSNotificationCenter defaultCenter] postNotificationName:VLCInputChangedNotification
+                                                            object:nil];
+    }
+
+    // Cancel pending resume dialogs
+    [[[VLCMain sharedInstance] resumeDialog] cancel];
+
+    input_thread_t *p_input_changed = NULL;
+
+    // object is hold here and released then it is dead
+    p_current_input = playlist_CurrentInput(pl_Get(getIntf()));
+    if (p_current_input) {
+        var_AddCallback(p_current_input, "intf-event", InputEvent, (__bridge void *)self);
+        [self playbackStatusUpdated];
+        [[o_main mainMenu] setRateControlsEnabled: YES];
+
+        if ([o_main activeVideoPlayback] && [[[o_main mainWindow] videoView] isHidden]) {
+            [[o_main mainWindow] changePlaylistState: psPlaylistItemChangedEvent];
+        }
+
+        p_input_changed = vlc_object_hold(p_current_input);
+
+        [[o_main playlist] currentlyPlayingItemChanged];
+
+        [[o_main playlist] continuePlaybackWhereYouLeftOff:p_current_input];
+
+        [[NSNotificationCenter defaultCenter] postNotificationName:VLCInputChangedNotification
+                                                            object:nil];
+    }
+
+    [self updateMetaAndInfo];
+
+    [self updateMainWindow];
+    [self updateDelays];
+    [self updateMainMenu];
+
+    /*
+     * Due to constraints within NSAttributedString's main loop runtime handling
+     * and other issues, we need to inform the extension manager on a separate thread.
+     * The serial queue ensures that changed inputs are propagated in the same order as they arrive.
+     */
+    dispatch_async(informInputChangedQueue, ^{
+        [[o_main extensionsManager] inputChanged:p_input_changed];
+        if (p_input_changed)
+            vlc_object_release(p_input_changed);
+    });
+}
+
+- (void)playbackStatusUpdated
+{
+    intf_thread_t *p_intf = getIntf();
+    int state = -1;
+    if (p_current_input) {
+        state = var_GetInteger(p_current_input, "state");
+    }
+
+    int i_control_itunes = var_InheritInteger(p_intf, "macosx-control-itunes");
+    // cancel itunes timer if next item starts playing
+    if (state > -1 && state != END_S && i_control_itunes > 0) {
+        if (o_itunes_play_timer) {
+            [o_itunes_play_timer invalidate];
+            o_itunes_play_timer = nil;
+        }
+    }
+
+    if (state == PLAYING_S) {
+        if (i_control_itunes > 0) {
+            // pause iTunes
+            if (!b_has_itunes_paused) {
+                iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
+                if (iTunesApp && [iTunesApp isRunning]) {
+                    if ([iTunesApp playerState] == iTunesEPlSPlaying) {
+                        msg_Dbg(p_intf, "pausing iTunes");
+                        [iTunesApp pause];
+                        b_has_itunes_paused = YES;
+                    }
+                }
+            }
+
+            // pause Spotify
+            if (!b_has_spotify_paused) {
+                SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
+
+                if (spotifyApp) {
+                    if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
+                        if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePlaying) {
+                            msg_Dbg(p_intf, "pausing Spotify");
+                            [spotifyApp pause];
+                            b_has_spotify_paused = YES;
+                        }
+                    }
+                }
+            }
+        }
+
+        BOOL shouldDisableScreensaver = var_InheritBool(p_intf, "disable-screensaver");
+
+        /* 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 */
+        if ([o_main activeVideoPlayback] && &IOPMAssertionDeclareUserActivity && shouldDisableScreensaver)
+        {
+            CFStringRef reasonForActivity = CFStringCreateWithCString(kCFAllocatorDefault, _("VLC media playback"), kCFStringEncodingUTF8);
+            IOReturn success = IOPMAssertionDeclareUserActivity(reasonForActivity,
+                                             kIOPMUserActiveLocal,
+                                             &userActivityAssertionID);
+            CFRelease(reasonForActivity);
+
+            if (success != kIOReturnSuccess)
+                msg_Warn(getIntf(), "failed to declare user activity");
+
+        }
+
+        /* prevent the system from sleeping */
+        if (systemSleepAssertionID > 0) {
+            msg_Dbg(getIntf(), "releasing old sleep blocker (%i)" , systemSleepAssertionID);
+            IOPMAssertionRelease(systemSleepAssertionID);
+        }
+
+        IOReturn success;
+        /* work-around a bug in 10.7.4 and 10.7.5, so check for 10.7.x < 10.7.4 and 10.8 */
+        if (NSAppKitVersionNumber < 1115.2) {
+            /* fall-back on the 10.5 mode, which also works on 10.7.4 and 10.7.5 */
+            if ([o_main activeVideoPlayback] && shouldDisableScreensaver)
+                success = IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &systemSleepAssertionID);
+            else
+                success = IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &systemSleepAssertionID);
+        } else {
+            CFStringRef reasonForActivity = CFStringCreateWithCString(kCFAllocatorDefault, _("VLC media playback"), kCFStringEncodingUTF8);
+            if ([o_main activeVideoPlayback] && shouldDisableScreensaver)
+                success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &systemSleepAssertionID);
+            else
+                success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reasonForActivity, &systemSleepAssertionID);
+            CFRelease(reasonForActivity);
+        }
+
+        if (success == kIOReturnSuccess)
+            msg_Dbg(getIntf(), "prevented sleep through IOKit (%i)", systemSleepAssertionID);
+        else
+            msg_Warn(getIntf(), "failed to prevent system sleep through IOKit");
+
+        [[o_main mainMenu] setPause];
+        [[o_main mainWindow] setPause];
+    } else {
+        [[o_main mainMenu] setSubmenusEnabled: FALSE];
+        [[o_main mainMenu] setPlay];
+        [[o_main mainWindow] setPlay];
+
+        /* allow the system to sleep again */
+        if (systemSleepAssertionID > 0) {
+            msg_Dbg(getIntf(), "releasing sleep blocker (%i)" , systemSleepAssertionID);
+            IOPMAssertionRelease(systemSleepAssertionID);
+        }
+
+        if (state == END_S || state == -1) {
+            /* continue playback where you left off */
+            if (p_current_input)
+                [[o_main playlist] storePlaybackPositionForItem:p_current_input];
+
+            if (i_control_itunes > 0) {
+                if (o_itunes_play_timer) {
+                    [o_itunes_play_timer invalidate];
+                }
+                o_itunes_play_timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
+                                                                       target: self
+                                                                     selector: @selector(resumeItunesPlayback:)
+                                                                     userInfo: nil
+                                                                      repeats: NO];
+            }
+        }
+    }
+
+    [self updateMainWindow];
+    [self sendDistributedNotificationWithUpdatedPlaybackStatus];
+}
+
+
+- (void)resumeItunesPlayback:(id)sender
+{
+    intf_thread_t *p_intf = getIntf();
+    if (var_InheritInteger(p_intf, "macosx-control-itunes") > 1) {
+        if (b_has_itunes_paused) {
+            iTunesApplication *iTunesApp = (iTunesApplication *) [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
+            if (iTunesApp && [iTunesApp isRunning]) {
+                if ([iTunesApp playerState] == iTunesEPlSPaused) {
+                    msg_Dbg(p_intf, "unpausing iTunes");
+                    [iTunesApp playpause];
+                }
+            }
+        }
+
+        if (b_has_spotify_paused) {
+            SpotifyApplication *spotifyApp = (SpotifyApplication *) [SBApplication applicationWithBundleIdentifier:@"com.spotify.client"];
+            if (spotifyApp) {
+                if ([spotifyApp respondsToSelector:@selector(isRunning)] && [spotifyApp respondsToSelector:@selector(playerState)]) {
+                    if ([spotifyApp isRunning] && [spotifyApp playerState] == kSpotifyPlayerStatePaused) {
+                        msg_Dbg(p_intf, "unpausing Spotify");
+                        [spotifyApp play];
+                    }
+                }
+            }
+        }
+    }
+
+    b_has_itunes_paused = NO;
+    b_has_spotify_paused = NO;
+    o_itunes_play_timer = nil;
+}
+
+- (void)updateMetaAndInfo
+{
+    if (!p_current_input) {
+        [[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:nil];
+        return;
+    }
+
+    input_item_t *p_input_item = input_GetItem(p_current_input);
+
+    [[[o_main playlist] model] updateItem:p_input_item];
+    [[[VLCMain sharedInstance] currentMediaInfoPanel] updatePanelWithItem:p_input_item];
+}
+
+- (void)updateMainWindow
+{
+    [[o_main mainWindow] updateWindow];
+}
+
+- (void)updateName
+{
+    [[o_main mainWindow] updateName];
+}
+
+- (void)updateDelays
+{
+    [[[VLCMain sharedInstance] trackSyncPanel] updateValues];
+}
+
+- (void)updateMainMenu
+{
+    [[o_main mainMenu] setupMenus];
+    [[o_main mainMenu] updatePlaybackRate];
+    [[VLCCoreInteraction sharedInstance] resetAtoB];
+}
+
+- (void)sendDistributedNotificationWithUpdatedPlaybackStatus
+{
+    [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"VLCPlayerStateDidChange"
+                                                                   object:nil
+                                                                 userInfo:nil
+                                                       deliverImmediately:YES];
+}
+
+- (BOOL)hasInput
+{
+    return p_current_input != NULL;
+}
+
+@end
index 02b38c7..ea86317 100644 (file)
@@ -43,7 +43,7 @@
 #include <vlc_variables.h>
 
 #import "CompatibilityFixes.h"
-#import "InputManager.h"
+#import "VLCInputManager.h"
 #import "MainMenu.h"
 #import "VideoView.h"
 #import "prefs.h"