]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/vout.m
macosx: experimental 64bit support
[vlc] / modules / gui / macosx / vout.m
index 89d369f7b98db2b1549313c5e30a9e9b966587b6..618831568b68bf9caed22e4c16564c31ed05863b 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * vout.m: MacOS X video output module
  *****************************************************************************
- * Copyright (C) 2001-2008 the VideoLAN team
+ * Copyright (C) 2001-2009 the VideoLAN team
  * $Id$
  *
  * Authors: Colin Delacroix <colin@zoy.org>
 #include <stdlib.h>                                                /* free() */
 #include <string.h>
 
-/* BeginFullScreen, EndFullScreen */
-#include <QuickTime/QuickTime.h>
+/* prevent system sleep */
+#import <CoreServices/CoreServices.h>
+#import <CoreServices/../Frameworks/OSServices.framework/Headers/Power.h>
+
+/* SystemUIMode */
+#import <Carbon/Carbon.h>
 
 #include <vlc_keys.h>
 
@@ -123,14 +127,19 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
 
 - (id)getViewForWindow: (id)o_window
 {
-    id o_enumerator = [o_embedded_array objectEnumerator];
-    id o_current_embedded;
-
-    while( (o_current_embedded = [o_enumerator nextObject]) )
+    if( o_embedded_array != nil )
     {
-        if( [o_current_embedded getWindow] == o_window )
+        id o_enumerator = [o_embedded_array objectEnumerator];
+        id o_current_embedded;
+        if( o_window != nil )
         {
-            return o_current_embedded;
+            while( (o_current_embedded = [o_enumerator nextObject]) )
+            {
+                if( [o_current_embedded getWindow] == o_window )
+                {
+                    return o_current_embedded;
+                }
+            }
         }
     }
     return nil;
@@ -145,7 +154,7 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
 
 - (id)initWithFrame: (NSRect)frameRect
 {
-    [super initWithFrame: frameRect];
+    self = [super initWithFrame: frameRect];
     p_vout = NULL;
     o_view = nil;
     s_frame = &frameRect;
@@ -330,7 +339,6 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
     vlc_object_release( p_input );
 }
 
-
 - (void)setOnTop:(BOOL)b_on_top
 {
     if( b_on_top )
@@ -438,15 +446,16 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
 
 - (void)snapshot
 {
-    vout_Control( p_real_vout, VOUT_SNAPSHOT );
+    var_TriggerCallback( p_real_vout, "video-snapshot" );
 }
 
 - (void)manage
 {
     /* Disable Screensaver, when we're playing something, but allow it on pause */
-    if( !VLCIntf || !VLCIntf->p_sys || !VLCIntf->p_sys->i_play_status )
+    if( !VLCIntf || !VLCIntf->p_sys )
         return;
 
+    UInt8 UsrActivity;
     if( VLCIntf->p_sys->i_play_status == PLAYING_S )
         UpdateSystemActivity( UsrActivity );
 }
@@ -480,7 +489,7 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
     if( i_pressed_modifiers & NSCommandKeyMask )
         val.i_int |= KEY_MODIFIER_COMMAND;
 
-    key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
+    key = [[[o_event charactersIgnoringModifiers] lowercaseString] characterAtIndex: 0];
 
     if( key )
     {
@@ -492,28 +501,23 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
                  [self toggleFullscreen];
              }
         }
-        else if ( key == ' ' )
+        else if ( p_vout )
         {
-            vlc_value_t val;
-            val.i_int = config_GetInt( p_vout, "key-play-pause" );
-            var_Set( p_vout->p_libvlc, "key-pressed", val );
-        }
-        else
-        {
-            val.i_int |= CocoaKeyToVLC( key );
+            if( key == ' ')
+                val.i_int = config_GetInt( p_vout, "key-play-pause" );
+            else
+                val.i_int |= (int)CocoaKeyToVLC( key );
             var_Set( p_vout->p_libvlc, "key-pressed", val );
         }
+        else NSLog( @"Could not send keyevent to VLC core" );
     }
     else
-    {
         [super keyDown: o_event];
-    }
 }
 
 - (void)mouseDown:(NSEvent *)o_event
 {
     vlc_value_t val;
-NSLog(@"Down");
     if( p_vout )
     {
         if( ( [o_event type] == NSLeftMouseDown ) &&
@@ -537,7 +541,7 @@ NSLog(@"Down");
                  ( [o_event modifierFlags] &  NSControlKeyMask ) ) )
         {
             msg_Dbg( p_vout, "received NSRightMouseDown (generic method) or Ctrl clic" );
-            [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
+            [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] voutView]];
         }
     }
 
@@ -563,7 +567,7 @@ NSLog(@"Down");
     if( p_vout && [o_event type] == NSRightMouseDown )
     {
         msg_Dbg( p_vout, "received NSRightMouseDown (specific method)" );
-        [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
+        [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] voutView]];
     }
 
     [super mouseDown: o_event];
@@ -575,9 +579,7 @@ NSLog(@"Down");
 
     if( p_vout && [o_event type] == NSLeftMouseUp )
     {
-        vlc_value_t b_val;
-        b_val.b_bool = true;
-        var_Set( p_vout, "mouse-clicked", b_val );
+        var_SetBool( p_vout, "mouse-clicked", true );
 
         var_Get( p_vout, "mouse-button-down", &val );
         val.i_int &= ~1;
@@ -608,7 +610,7 @@ NSLog(@"Down");
         /* FIXME: this isn't the appropriate place, but we can't receive
          * NSRightMouseDown some how */
         msg_Dbg( p_vout, "received NSRightMouseUp" );
-        [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
+        [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] voutView]];
     }
 
     [super mouseUp: o_event];
@@ -699,26 +701,21 @@ NSLog(@"Down");
 {
     /* p_real_vout: the vout we have to use to check for video-on-top
        and a few other things. If we are the QuickTime output, it's us.
-       It we are the OpenGL provider, it is our parent. */
-    if( p_vout->i_object_type == VLC_OBJECT_OPENGL )
-    {
-        return (vout_thread_t *) p_vout->p_parent;
-    }
-    else
-    {
-        return p_vout;
-    }
-
+       It we are the OpenGL provider, it is our parent.
+       Since we can't be the QuickTime output anymore, we need to be
+       the parent.
+       FIXME: check with the caca and x11 vouts! */
+    return (vout_thread_t *) p_vout->p_parent;
 }
 
-+ (id)getVoutView: (vout_thread_t *)p_vout subView: (NSView *)view
-                                    frame: (NSRect *)s_frame
++ (id)voutView: (vout_thread_t *)p_vout subView: (NSView *)view
+         frame: (NSRect *)s_frame
 {
-    vlc_value_t value_drawable;
+    int i_drawable_gl;
     int i_timeout;
     id o_return = nil;
 
-    var_Get( p_vout->p_libvlc, "drawable", &value_drawable );
+    i_drawable_gl = var_GetInteger( p_vout->p_libvlc, "drawable-gl" );
 
     var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
     var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
@@ -729,9 +726,9 @@ NSLog(@"Down");
 
     /* We only wait for NSApp to initialise if we're not embedded (as in the
      * case of the Mozilla plugin).  We can tell whether we're embedded or not
-     * by examining the "drawable" value: if it's zero, we're running in the
+     * by examining the "drawable-gl" value: if it's zero, we're running in the
      * main Mac intf; if it's non-zero, we're embedded. */
-    if( value_drawable.i_int == 0 )
+    if( i_drawable_gl == 0 )
     {
         /* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
         for( i_timeout = 20 ; i_timeout-- ; )
@@ -774,7 +771,7 @@ NSLog(@"Down");
 - (void)enterFullscreen
 {
     /* Save the settings for next playing item */
-    playlist_t * p_playlist = pl_Yield( p_real_vout );
+    playlist_t * p_playlist = pl_Hold( p_real_vout );
     var_SetBool( p_playlist, "fullscreen", true );
     pl_Release( p_real_vout );
 }
@@ -782,7 +779,7 @@ NSLog(@"Down");
 - (void)leaveFullscreen
 {
     /* Save the settings for next playing item */
-    playlist_t * p_playlist = pl_Yield( p_real_vout );
+    playlist_t * p_playlist = pl_Hold( p_real_vout );
     var_SetBool( p_playlist, "fullscreen", false );
     pl_Release( p_real_vout );
 }
@@ -806,7 +803,7 @@ NSLog(@"Down");
     return YES;
 }
 
-- (bool)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
+- (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
                      frame: (NSRect *) s_arg_frame
 {
     BOOL b_return = [super setVout: p_arg_vout subView: view frame:s_arg_frame];
@@ -858,13 +855,18 @@ NSLog(@"Down");
 
 - (void)manage
 {
+    /* Dooh, why do we spend processor time doing this kind of stuff? */
     [super manage];
     unsigned int i_mouse_hide_timeout =
-        var_GetInteger(p_vout, "mouse-hide-timeout") * 1000;
+        var_CreateGetInteger(p_vout, "mouse-hide-timeout") * 1000;
+
+    if( i_mouse_hide_timeout < 100000 )
+        i_mouse_hide_timeout = 100000;
     if( p_vout->b_fullscreen )
     {
         if( mdate() - i_time_mouse_last_moved > i_mouse_hide_timeout )
         {
+            i_time_mouse_last_moved = mdate();
             [self hideMouse: YES];
         }
     }
@@ -877,17 +879,26 @@ NSLog(@"Down");
 
 - (void)enterFullscreen
 {
-    [super enterFullscreen];
     [o_window performSelectorOnMainThread: @selector(enterFullscreen) withObject: NULL waitUntilDone: NO];
+    [super enterFullscreen];
 
 }
 
 - (void)leaveFullscreen
 {
-    [super leaveFullscreen];
     [o_window performSelectorOnMainThread: @selector(leaveFullscreen) withObject: NULL waitUntilDone: NO];
+    [super leaveFullscreen];
 }
 
+
+- (void)scaleWindowWithFactor: (float)factor animate: (BOOL)animate
+{
+    if( p_vout->b_fullscreen )
+        return;
+    [o_window setMovableByWindowBackground: NO];
+    [super scaleWindowWithFactor: factor animate: animate];
+    [o_window setMovableByWindowBackground: YES];
+}
 @end
 
 /*****************************************************************************
@@ -931,7 +942,7 @@ NSLog(@"Down");
 
         [o_window setAcceptsMouseMovedEvents: TRUE];
 
-        if( var_GetBool( p_real_vout, "video-on-top" ) )
+        if( var_CreateGetBool( p_real_vout, "video-on-top" ) )
         {
             [o_window setLevel: NSStatusWindowLevel];
         }
@@ -990,7 +1001,6 @@ NSLog(@"Down");
     /* FIXME: fix core */
     [o_embeddedwindow performSelector:@selector(orderOut:) withObject:nil afterDelay:3.];
 
-    [o_window setAcceptsMouseMovedEvents: NO];
     [[[VLCMain sharedInstance] getEmbeddedList] releaseEmbeddedVout: self];
 }
 
@@ -1046,12 +1056,16 @@ NSLog(@"Down");
         [self center];
         [self makeKeyAndOrderFront: self];
         [self setReleasedWhenClosed: YES];
+        [self setFrameUsingName:@"VLCVoutWindowDetached"];
+        [self setFrameAutosaveName:@"VLCVoutWindowDetached"];
 
         /* We'll catch mouse events */
         [self makeFirstResponder: o_view];
         [self setCanBecomeKeyWindow: YES];
+        [self setAcceptsMouseMovedEvents: YES];
+        [self setIgnoresMouseEvents: NO];
 
-        if( var_GetBool( p_vout, "macosx-background" ) )
+        if( var_CreateGetBool( p_vout, "macosx-background" ) )
         {
             int i_device = var_GetInteger( p_vout->p_libvlc, "video-device" );
 
@@ -1068,12 +1082,12 @@ NSLog(@"Down");
             [self setLevel: CGWindowLevelForKey(kCGDesktopWindowLevelKey)];
             [self setMovableByWindowBackground: NO];
         }
-        if( var_GetBool( p_vout, "video-on-top" ) )
+        if( var_CreateGetBool( p_vout, "video-on-top" ) )
         {
             [self setLevel: NSStatusWindowLevel];
         }
 
-        [self setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
+        [self setAlphaValue: var_CreateGetFloat( p_vout, "macosx-opaqueness" )];
 
         /* Add the view. It's automatically resized to fit the window */
         [self setContentView: o_view];
@@ -1092,35 +1106,28 @@ NSLog(@"Down");
     BOOL b_black = NO;
 
     i_device = var_GetInteger( p_vout->p_libvlc, "video-device" );
-    b_black = var_GetBool( p_vout, "macosx-black" );
+    b_black = var_CreateGetBool( p_vout, "macosx-black" );
 
     /* Find out on which screen to open the window */
     screen = [NSScreen screenWithDisplayID: (CGDirectDisplayID)i_device];
     if( !screen ) screen = [self screen];
 
-    if( b_black && [[NSScreen screens] count] > 1)
-    {
-        CGDisplayFadeReservationToken token;
-        CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
-        CGDisplayFade( token, 0.2 , kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, YES );
-
+    if( b_black )
         [screen blackoutOtherScreens];
 
-        CGDisplayFade( token, 0.1 , kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, NO );
-        CGReleaseDisplayFadeReservation( token);
-    }
-
     [self setMovableByWindowBackground: NO];
 
-    /* tell the fspanel to move itself to front next time it's triggered */
-    [[[[VLCMain sharedInstance] getControls] getFSPanel] setVoutWasUpdated: i_device];
-    [[[[VLCMain sharedInstance] getControls] getFSPanel] setActive: nil];
-
     if( [screen isMainScreen] )
         SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
 
     initialFrame = [self frame];
     [self setFrame:[screen frame] display:YES animate:YES];
+    [self setLevel:NSNormalWindowLevel];
+
+    /* tell the fspanel to move itself to front next time it's triggered */
+    [[[[VLCMain sharedInstance] getControls] getFSPanel] setVoutWasUpdated: i_device];
+    [[[[VLCMain sharedInstance] getControls] getFSPanel] setActive: nil];
+
     fullscreen = YES;
 }
 
@@ -1135,9 +1142,11 @@ NSLog(@"Down");
     SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
     [self setFrame:initialFrame display:YES animate:YES];
     [self setMovableByWindowBackground: YES];
+    if( var_GetBool( p_vout, "video-on-top" ) )
+        [self setLevel: NSStatusWindowLevel];
 }
 
-- (id)getVoutView // FIXME Naming scheme!
+- (id)voutView
 {
     return o_view;
 }