]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/intf.m
macosx: use CoreInteraction code for the media key triggers
[vlc] / modules / gui / macosx / intf.m
index f3766ceaf1f737b9631ac85057f76e0382da1995..f7e36d751283fbe11ef23fb0713b6fef958929c3 100644 (file)
@@ -97,6 +97,7 @@ int OpenIntf ( vlc_object_t *p_this )
 {
     NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
     [VLCApplication sharedApplication];
+
     intf_thread_t *p_intf = (intf_thread_t*) p_this;
 
     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
@@ -106,9 +107,9 @@ int OpenIntf ( vlc_object_t *p_this )
     memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
 
     /* subscribe to LibVLCCore's messages */
-    p_intf->p_sys->p_sub = vlc_Subscribe( MsgCallback, NULL );
-    p_intf->pf_run = Run;
-    p_intf->b_should_run_on_first_thread = true;
+    vlc_Subscribe( &p_intf->p_sys->sub, MsgCallback, NULL );
+
+    Run( p_intf );
 
     [o_pool release];
     return VLC_SUCCESS;
@@ -169,7 +170,8 @@ static int WindowControl( vout_window_t *p_wnd, int i_query, va_list args )
     else if( i_query == VOUT_WINDOW_SET_FULLSCREEN )
     {
         NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
-        [[VLCMain sharedInstance] fullscreenChanged];
+        // we already have our playlist "fullscreen" callback, do not repeat the same call here
+        //[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(fullscreenChanged) withObject: nil waitUntilDone: NO];
         [o_pool release];
     }
     else
@@ -204,6 +206,8 @@ static void Run( intf_thread_t *p_intf )
     [[VLCMain sharedInstance] applicationWillTerminate:nil];
     [o_appLock release];
     [o_pool release];
+
+    raise(SIGTERM);
 }
 
 #pragma mark -
@@ -618,6 +622,28 @@ static VLCMain *_o_sharedMainInstance = nil;
     if( OSX_LION )
         b_nativeFullscreenMode = config_GetInt( 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.
+         * Note: this icon doesn't represent an endorsement of The Coca-Cola Company.
+         */
+        NSCalendar *gregorian =
+        [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
+        NSUInteger dayOfYear = [gregorian ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];
+        [gregorian release];
+
+        if (dayOfYear >= 354)
+            [[VLCApplication sharedApplication] setApplicationIconImage: [NSImage imageNamed:@"vlc-xmas"]];
+    }
+
     nib_main_loaded = TRUE;
 }
 
@@ -625,6 +651,8 @@ static VLCMain *_o_sharedMainInstance = nil;
 {
     if( !p_intf ) return;
 
+    [self updateCurrentlyUsedHotkeys];
+
     [o_mainwindow updateWindow];
     [o_mainwindow updateTimeSlider];
     [o_mainwindow updateVolumeSlider];
@@ -766,13 +794,13 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_embedded_list release];
     [o_coredialogs release];
     [o_eyetv release];
-    [o_mainwindow release];
 
     /* unsubscribe from libvlc's debug messages */
-    vlc_Unsubscribe( p_intf->p_sys->p_sub );
+    vlc_Unsubscribe( &p_intf->p_sys->sub );
 
     [o_msg_arr removeAllObjects];
     [o_msg_arr release];
+    o_msg_arr = NULL;
 
     [o_msg_lock release];
 
@@ -786,6 +814,9 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     libvlc_Quit( p_intf->p_libvlc );
 
+    [o_mainwindow release];
+    o_mainwindow = NULL;
+
     [self setIntf:nil];
 }
 
@@ -814,15 +845,15 @@ static VLCMain *_o_sharedMainInstance = nil;
         int keyRepeat = (keyFlags & 0x1);
 
         if( keyCode == NX_KEYTYPE_PLAY && keyState == 0 )
-            var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
+            [[VLCCoreInteraction sharedInstance] play];
 
-        if( keyCode == NX_KEYTYPE_FAST && !b_mediakeyJustJumped )
+        if( (keyCode == NX_KEYTYPE_FAST || keyCode == NX_KEYTYPE_NEXT) && !b_mediakeyJustJumped )
         {
             if( keyState == 0 && keyRepeat == 0 )
-                var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_NEXT );
+                [[VLCCoreInteraction sharedInstance] next];
             else if( keyRepeat == 1 )
             {
-                var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
+                [[VLCCoreInteraction sharedInstance] forwardShort];
                 b_mediakeyJustJumped = YES;
                 [self performSelector:@selector(resetMediaKeyJump)
                            withObject: NULL
@@ -830,13 +861,13 @@ static VLCMain *_o_sharedMainInstance = nil;
             }
         }
 
-        if( keyCode == NX_KEYTYPE_REWIND && !b_mediakeyJustJumped )
+        if( (keyCode == NX_KEYTYPE_REWIND || keyCode == NX_KEYTYPE_PREVIOUS) && !b_mediakeyJustJumped )
         {
             if( keyState == 0 && keyRepeat == 0 )
-                var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PREV );
+                [[VLCCoreInteraction sharedInstance] previous];
             else if( keyRepeat == 1 )
             {
-                var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT );
+                [[VLCCoreInteraction sharedInstance] backwardShort];
                 b_mediakeyJustJumped = YES;
                 [self performSelector:@selector(resetMediaKeyJump)
                            withObject: NULL
@@ -1266,8 +1297,8 @@ unsigned int CocoaKeyToVLC( unichar i_key )
     unsigned int i_pressed_modifiers = 0;
     const struct hotkey *p_hotkeys;
     int i;
-    NSMutableString *tempString = [[[NSMutableString alloc] init] autorelease];
-    NSMutableString *tempStringPlus = [[[NSMutableString alloc] init] autorelease];
+    NSMutableString *tempString = [[NSMutableString alloc] init];
+    NSMutableString *tempStringPlus = [[NSMutableString alloc] init];
 
     val.i_int = 0;
     p_hotkeys = p_intf->p_libvlc->p_hotkeys;
@@ -1304,6 +1335,8 @@ unsigned int CocoaKeyToVLC( unichar i_key )
     if( key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask )
     {
         [[VLCCoreInteraction sharedInstance] toggleFullscreen];
+        [tempString release];
+        [tempStringPlus release];
         return YES;
     }
 
@@ -1319,12 +1352,16 @@ unsigned int CocoaKeyToVLC( unichar i_key )
         case NSLeftArrowFunctionKey:
         case NSEnterCharacter:
         case NSCarriageReturnCharacter:
+            [tempString release];
+            [tempStringPlus release];
             return NO;
     }
 
     if( key == 0x0020 ) // space key
     {
         [[VLCCoreInteraction sharedInstance] play];
+        [tempString release];
+        [tempStringPlus release];
         return YES;
     }
 
@@ -1333,9 +1370,13 @@ unsigned int CocoaKeyToVLC( unichar i_key )
     if( [o_usedHotkeys indexOfObject: tempString] != NSNotFound || [o_usedHotkeys indexOfObject: tempStringPlus] != NSNotFound )
     {
         var_SetInteger( p_intf->p_libvlc, "key-pressed", val.i_int );
+        [tempString release];
+        [tempStringPlus release];
         return YES;
     }
 
+    [tempString release];
+    [tempStringPlus release];
     return NO;
 }
 
@@ -1363,7 +1404,8 @@ unsigned int CocoaKeyToVLC( unichar i_key )
         }
     }
     module_config_free (p_config);
-    o_usedHotkeys = [[NSArray alloc] initWithArray: o_usedHotkeys copyItems: YES];
+    o_usedHotkeys = [[NSArray alloc] initWithArray: o_tempArray copyItems: YES];
+    [o_tempArray release];
 }
 
 #pragma mark -
@@ -1375,7 +1417,11 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 
     if (b_nativeFullscreenMode)
     {
-        [o_mainwindow toggleFullScreen: self];
+        // 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
@@ -1418,7 +1464,7 @@ unsigned int CocoaKeyToVLC( unichar i_key )
         if( p_current_input )
         {
             var_AddCallback( p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance] );
-
+            [self playbackStatusUpdated];
             [o_mainmenu setRateControlsEnabled: YES];
             if ( [self activeVideoPlayback] && [[o_mainwindow videoView] isHidden] )
                 [o_mainwindow performSelectorOnMainThread:@selector(togglePlaylist:) withObject: nil waitUntilDone:NO];
@@ -1706,8 +1752,11 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 - (void)setActiveVideoPlayback:(BOOL)b_value
 {
     b_active_videoplayback = b_value;
-    [o_mainwindow performSelectorOnMainThread:@selector(setVideoplayEnabled) withObject: nil waitUntilDone:NO];
-    [o_mainwindow performSelectorOnMainThread:@selector(togglePlaylist:) withObject: nil waitUntilDone:NO];
+    if( o_mainwindow )
+    {
+        [o_mainwindow performSelectorOnMainThread:@selector(setVideoplayEnabled) withObject:nil waitUntilDone:YES];
+        [o_mainwindow performSelectorOnMainThread:@selector(togglePlaylist:) withObject:nil waitUntilDone:NO];
+    }
 }
 
 - (BOOL)activeVideoPlayback
@@ -1857,42 +1906,55 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 - (void)_removeOldPreferences
 {
     static NSString * kVLCPreferencesVersion = @"VLCPreferencesVersion";
-    static const int kCurrentPreferencesVersion = 1;
+    static const int kCurrentPreferencesVersion = 2;
     int version = [[NSUserDefaults standardUserDefaults] integerForKey:kVLCPreferencesVersion];
     if( version >= kCurrentPreferencesVersion ) return;
 
-    NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
-        NSUserDomainMask, YES);
-    if( !libraries || [libraries count] == 0) return;
-    NSString * preferences = [[libraries objectAtIndex:0] stringByAppendingPathComponent:@"Preferences"];
-
-    /* File not found, don't attempt anything */
-    if(![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"VLC"]] &&
-       ![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"org.videolan.vlc.plist"]] )
+    if( version == 1 )
     {
         [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
-        return;
-    }
+        [[NSUserDefaults standardUserDefaults] synchronize];
 
-    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 )
-    {
-        [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
-        return;
+        if (![[VLCCoreInteraction sharedInstance] fixPreferences])
+            return;
+        else
+            config_SaveConfigFile( VLCIntf ); // we need to do manually, since we won't quit libvlc cleanly
     }
+    else
+    {
+        NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
+            NSUserDomainMask, YES);
+        if( !libraries || [libraries count] == 0) return;
+        NSString * preferences = [[libraries objectAtIndex:0] stringByAppendingPathComponent:@"Preferences"];
+
+        /* File not found, don't attempt anything */
+        if(![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"org.videolan.vlc"]] &&
+           ![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"org.videolan.vlc.plist"]] )
+        {
+            [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
+            return;
+        }
 
-    NSArray * ourPreferences = [NSArray arrayWithObjects:@"org.videolan.vlc.plist", @"VLC", nil];
+        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 )
+        {
+            [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
+            return;
+        }
 
-    /* Move the file to trash so that user can find them later */
-    [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:preferences destination:nil files:ourPreferences tag:0];
+        NSArray * ourPreferences = [NSArray arrayWithObjects:@"org.videolan.vlc.plist", @"VLC", @"org.videolan.vlc", nil];
 
-    /* really reset the defaults from now on */
-    [NSUserDefaults resetStandardUserDefaults];
+        /* Move the file to trash so that user can find them later */
+        [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:preferences destination:nil files:ourPreferences tag:0];
 
-    [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
-    [[NSUserDefaults standardUserDefaults] synchronize];
+        /* really reset the defaults from now on */
+        [NSUserDefaults resetStandardUserDefaults];
+
+        [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
+        [[NSUserDefaults standardUserDefaults] synchronize];
+    }
 
     /* Relaunch now */
     const char * path = [[[NSBundle mainBundle] executablePath] UTF8String];
@@ -1948,36 +2010,39 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 
 - (void)processReceivedlibvlcMessage:(const msg_item_t *) item ofType: (int)i_type withStr: (char *)str
 {
-    NSColor *o_white = [NSColor whiteColor];
-    NSColor *o_red = [NSColor redColor];
-    NSColor *o_yellow = [NSColor yellowColor];
-    NSColor *o_gray = [NSColor grayColor];
-    NSString * firstString, * secondString;
+    if (o_msg_arr)
+    {
+        NSColor *o_white = [NSColor whiteColor];
+        NSColor *o_red = [NSColor redColor];
+        NSColor *o_yellow = [NSColor yellowColor];
+        NSColor *o_gray = [NSColor grayColor];
+        NSString * firstString, * secondString;
 
-    NSColor * pp_color[4] = { o_white, o_red, o_yellow, o_gray };
-    static const char * ppsz_type[4] = { ": ", " error: ", " warning: ", " debug: " };
+        NSColor * pp_color[4] = { o_white, o_red, o_yellow, o_gray };
+        static const char * ppsz_type[4] = { ": ", " error: ", " warning: ", " debug: " };
 
-    NSDictionary *o_attr;
-    NSMutableAttributedString *o_msg_color;
+        NSDictionary *o_attr;
+        NSMutableAttributedString *o_msg_color;
 
-    [o_msg_lock lock];
+        [o_msg_lock lock];
 
-    if( [o_msg_arr count] + 2 > 600 )
-    {
-        [o_msg_arr removeObjectAtIndex: 0];
-        [o_msg_arr removeObjectAtIndex: 1];
-    }
-    firstString = [NSString stringWithFormat:@"%s%s", item->psz_module, ppsz_type[i_type]];
-    secondString = [NSString stringWithFormat:@"%@%s\n", firstString, str];
+        if( [o_msg_arr count] + 2 > 600 )
+        {
+            [o_msg_arr removeObjectAtIndex: 0];
+            [o_msg_arr removeObjectAtIndex: 1];
+        }
+        firstString = [NSString stringWithFormat:@"%s%s", item->psz_module, ppsz_type[i_type]];
+        secondString = [NSString stringWithFormat:@"%@%s\n", firstString, str];
 
-    o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type]  forKey: NSForegroundColorAttributeName];
-    o_msg_color = [[NSMutableAttributedString alloc] initWithString: secondString attributes: o_attr];
-    o_attr = [NSDictionary dictionaryWithObject: pp_color[3] forKey: NSForegroundColorAttributeName];
-    [o_msg_color setAttributes: o_attr range: NSMakeRange( 0, [firstString length] )];
-    [o_msg_arr addObject: [o_msg_color autorelease]];
+        o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type]  forKey: NSForegroundColorAttributeName];
+        o_msg_color = [[NSMutableAttributedString alloc] initWithString: secondString attributes: o_attr];
+        o_attr = [NSDictionary dictionaryWithObject: pp_color[3] forKey: NSForegroundColorAttributeName];
+        [o_msg_color setAttributes: o_attr range: NSMakeRange( 0, [firstString length] )];
+        [o_msg_arr addObject: [o_msg_color autorelease]];
 
-    b_msg_arr_changed = YES;
-    [o_msg_lock unlock];
+        b_msg_arr_changed = YES;
+        [o_msg_lock unlock];
+    }
 }
 
 - (IBAction)saveDebugLog:(id)sender
@@ -2049,30 +2114,14 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 - (void)coreChangedMediaKeySupportSetting: (NSNotification *)o_notification
 {
     b_mediaKeySupport = config_GetInt( VLCIntf, "macosx-mediakeys" );
-    if (b_mediaKeySupport) {
+    if (b_mediaKeySupport)
+    {
         if (!o_mediaKeyController)
             o_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
         [o_mediaKeyController startWatchingMediaKeys];
     }
     else if (!b_mediaKeySupport && o_mediaKeyController)
-    {
-        int returnedValue = NSRunInformationalAlertPanel(_NS("Relaunch required"),
-                                               _NS("To make sure that VLC no longer listens to your media key events, it needs to be restarted."),
-                                               _NS("Relaunch VLC"), _NS("Ignore"), nil, nil);
-        if( returnedValue == NSOKButton )
-        {
-            /* 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);
-                return;
-            }
-            execl(path, path, NULL);
-        }
-    }
+        [o_mediaKeyController stopWatchingMediaKeys];
 }
 
 @end
@@ -2085,7 +2134,7 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 // when user selects the quit menu from dock it sends a terminate:
 // but we need to send a stop: to properly exits libvlc.
 // However, we are not able to change the action-method sent by this standard menu item.
-// thus we override terminat: to send a stop:
+// thus we override terminate: to send a stop:
 // see [af97f24d528acab89969d6541d83f17ce1ecd580] that introduced the removal of setjmp() and longjmp()
 - (void)terminate:(id)sender
 {