vout_thread_t *p_vout = vlc_object_find( VLCIntf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
BOOL blackout_other_displays = var_GetBool( p_vout, "macosx-black" );
- /* We should get the screen pointed by var_GetInteger( p_vout, "video-device" ) */
- screen = [self screen];
+ screen = [NSScreen screenWithDisplayID:(CGDirectDisplayID)var_GetInteger( p_vout, "video-device" )];
vlc_object_release( p_vout );
+ if (!screen)
+ screen = [self screen];
+
screen_rect = [screen frame];
[o_btn_fullscreen setState: YES];
[NSCursor setHiddenUntilMouseMoves: YES];
if (blackout_other_displays)
- ; /* We should do something like [screen blackoutOtherScreens]; */
+ [screen blackoutOtherScreens]; /* We should do something like [screen blackoutOtherScreens]; */
/* Only create the o_fullscreen_window if we are not in the middle of the zooming animation */
if (!o_fullscreen_window)
[o_fullscreen_window setAcceptsMouseMovedEvents: TRUE];
/* tell the fspanel to move itself to front next time it's triggered */
- [[[[VLCMain sharedInstance] getControls] getFSPanel] setVoutWasUpdated: 0 /* Get this right */];
+ [[[[VLCMain sharedInstance] getControls] getFSPanel] setVoutWasUpdated: (int)[[o_fullscreen_window screen] displayID]];
[[[[VLCMain sharedInstance] getControls] getFSPanel] setActive: nil];
}
[o_btn_fullscreen setState: NO];
+ /* We always try to do so */
+ [NSScreen unblackoutScreens];
+
/* Don't do anything if o_fullscreen_window is already closed */
if (!o_fullscreen_window)
return;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+#import <ApplicationServices/ApplicationServices.h>
+
+/*****************************************************************************
+ * NSAnimation (VLCAddition)
+ *****************************************************************************/
+
+@interface NSAnimation (VLCAdditions)
+- (void)setUserInfo: (void *)userInfo;
+- (void *)userInfo;
+@end
+
+/*****************************************************************************
+ * NSScreen (VLCAdditions)
+ *
+ * Missing extension to NSScreen
+ *****************************************************************************/
+
+@interface NSScreen (VLCAdditions)
+
++ (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID;
+- (CGDirectDisplayID)displayID;
+- (void)blackoutOtherScreens;
++ (void)unblackoutScreens;
+@end
+
/*****************************************************************************
* VLCWindow
*
{
BOOL b_canBecomeKeyWindow;
BOOL b_isset_canBecomeKeyWindow;
+ NSViewAnimation *animation;
}
- (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey;
+
+/* animate mode is only supported in >=10.4 */
+- (void)orderFront: (id)sender animate: (BOOL)animate;
+
+/* animate mode is only supported in >=10.4 */
+- (void)orderOut: (id)sender animate: (BOOL)animate;
+
+/* animate mode is only supported in >=10.4 */
+- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback;
+
+/* animate mode is only supported in >=10.4 */
+- (void)closeAndAnimate: (BOOL)animate;
@end
#include "playlist.h"
#include "controls.h"
+/*****************************************************************************
+ * NSAnimation (VLCAdditions)
+ *
+ * Missing extension to NSAnimation
+ *****************************************************************************/
+
+@implementation NSAnimation (VLCAdditions)
+/* fake class attributes */
+static NSMapTable *VLCAdditions_userInfo = NULL;
+
++ (void)load
+{
+ /* init our fake object attribute */
+ VLCAdditions_userInfo = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 16);
+}
+
+- (void)dealloc
+{
+ NSMapRemove(VLCAdditions_userInfo, self);
+ [super dealloc];
+}
+
+- (void)setUserInfo: (void *)userInfo
+{
+ NSMapInsert(VLCAdditions_userInfo, self, (void*)userInfo);
+}
+
+- (void *)userInfo
+{
+ return NSMapGet(VLCAdditions_userInfo, self);
+}
+@end
+
+/*****************************************************************************
+ * NSScreen (VLCAdditions)
+ *
+ * Missing extension to NSScreen
+ *****************************************************************************/
+
+@implementation NSScreen (VLCAdditions)
+
+static NSMutableArray *blackoutWindows = NULL;
+
++ (void)load
+{
+ /* init our fake object attribute */
+ blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
+}
+
++ (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
+{
+ int i;
+
+ for( i = 0; i < [[NSScreen screens] count]; i++ )
+ {
+ NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
+ if([screen displayID] == displayID)
+ return screen;
+ }
+ return nil;
+}
+
+- (CGDirectDisplayID)displayID
+{
+ return (CGDirectDisplayID)_screenNumber;
+}
+
+- (void)blackoutOtherScreens
+{
+ unsigned int i;
+
+ /* Free our previous blackout window (follow blackoutWindow alloc strategy) */
+ [blackoutWindows makeObjectsPerformSelector:@selector(close)];
+ [blackoutWindows removeAllObjects];
+
+
+ for(i = 0; i < [[NSScreen screens] count]; i++)
+ {
+ VLCWindow *blackoutWindow;
+ NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
+ if(self == screen)
+ continue;
+ /* blackoutWindow alloc strategy
+ - The NSMutableArray blackoutWindows has the blackoutWindow references
+ - blackoutOtherDisplays is responsible for alloc/releasing its Windows
+ */
+ blackoutWindow = [[VLCWindow alloc] initWithContentRect: [screen frame] styleMask: NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ [blackoutWindow setBackgroundColor:[NSColor blackColor]];
+ [blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
+
+ [blackoutWindow orderFront: self animate: YES];
+
+ [blackoutWindows addObject: blackoutWindow];
+ [blackoutWindow release];
+ }
+}
+
++ (void)unblackoutScreens
+{
+ unsigned int i;
+
+ for(i = 0; i < [blackoutWindows count]; i++)
+ {
+ VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
+ [blackoutWindow closeAndAnimate: YES];
+ }
+}
+
+@end
+
/*****************************************************************************
* VLCWindow
*
return [super canBecomeKeyWindow];
}
+
+- (void)closeAndAnimate: (BOOL)animate
+{
+ NSInvocation *invoc;
+
+ if (!animate || MACOS_VERSION < 10.4f)
+ {
+ [super close];
+ return;
+ }
+
+ invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(close)]];
+ [invoc setTarget: (id)super];
+
+ if (![self isVisible] || [self alphaValue] == 0.0)
+ {
+ [super close];
+ return;
+ }
+
+ [self orderOut: self animate: YES callback: invoc];
+}
+
+- (void)orderOut: (id)sender animate: (BOOL)animate
+{
+ NSInvocation *invoc = [NSInvocation invocationWithMethodSignature:[super methodSignatureForSelector:@selector(orderOut:)]];
+ [invoc setTarget: (id)super];
+ [invoc setArgument: sender atIndex: 0];
+ [self orderOut: sender animate: animate callback: invoc];
+}
+
+- (void)orderOut: (id)sender animate: (BOOL)animate callback:(NSInvocation *)callback
+{
+ NSViewAnimation *anim;
+ NSViewAnimation *current_anim;
+ NSMutableDictionary *dict;
+
+ if (!animate || MACOS_VERSION < 10.4f)
+ {
+ [self orderOut: sender];
+ return;
+ }
+
+ dict = [[NSMutableDictionary alloc] initWithCapacity:2];
+
+ [dict setObject:self forKey:NSViewAnimationTargetKey];
+
+ [dict setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
+ anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
+ [dict release];
+
+ [anim setAnimationBlockingMode:NSAnimationNonblocking];
+ [anim setDuration:0.9];
+ [anim setFrameRate:30];
+ [anim setUserInfo: callback];
+
+ @synchronized(self) {
+ current_anim = self->animation;
+
+ if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeOutEffect && [current_anim isAnimating])
+ {
+ [anim release];
+ }
+ else
+ {
+ if (current_anim)
+ {
+ [current_anim stopAnimation];
+ [anim setCurrentProgress:1.0-[current_anim currentProgress]];
+ [current_anim release];
+ }
+ else
+ [anim setCurrentProgress:1.0 - [self alphaValue]];
+ self->animation = anim;
+ [self setDelegate: self];
+ [anim startAnimation];
+ }
+ }
+}
+
+- (void)orderFront: (id)sender animate: (BOOL)animate
+{
+ NSViewAnimation *anim;
+ NSViewAnimation *current_anim;
+ NSMutableDictionary *dict;
+
+ if (!animate || MACOS_VERSION < 10.4f)
+ {
+ [super orderFront: sender];
+ [self setAlphaValue: 1.0];
+ return;
+ }
+
+ if (![self isVisible])
+ {
+ [self setAlphaValue: 0.0];
+ [super orderFront: sender];
+ }
+ else if ([self alphaValue] == 1.0)
+ {
+ [super orderFront: self];
+ return;
+ }
+
+ dict = [[NSMutableDictionary alloc] initWithCapacity:2];
+
+ [dict setObject:self forKey:NSViewAnimationTargetKey];
+
+ [dict setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
+ anim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict, nil]];
+ [dict release];
+
+ [anim setAnimationBlockingMode:NSAnimationNonblocking];
+ [anim setDuration:0.5];
+ [anim setFrameRate:30];
+
+ @synchronized(self) {
+ current_anim = self->animation;
+
+ if ([[[current_anim viewAnimations] objectAtIndex:0] objectForKey: NSViewAnimationEffectKey] == NSViewAnimationFadeInEffect && [current_anim isAnimating])
+ {
+ [anim release];
+ }
+ else
+ {
+ if (current_anim)
+ {
+ [current_anim stopAnimation];
+ [anim setCurrentProgress:1.0 - [current_anim currentProgress]];
+ [current_anim release];
+ }
+ else
+ [anim setCurrentProgress:[self alphaValue]];
+ self->animation = anim;
+ [self setDelegate: self];
+ [self orderFront: sender];
+ [anim startAnimation];
+ }
+ }
+}
+
+- (void)animationDidEnd:(NSAnimation*)anim
+{
+ if ([self alphaValue] <= 0.0)
+ {
+ NSInvocation * invoc;
+ [super orderOut: nil];
+ [self setAlphaValue: 1.0];
+ if ((invoc = [anim userInfo]))
+ [invoc invoke];
+ }
+}
@end
/*****************************************************************************
(int)s_rect.size.width, (int)s_rect.size.height );
text.psz_string = psz_temp;
- val2.i_int = i;
+ val2.i_int = (int)[o_screen displayID];
var_Change( p_real_vout, "video-device",
VLC_VAR_ADDCHOICE, &val2, &text );
- if( i == i_device )
+ if( (int)[o_screen displayID] == i_device )
{
var_Set( p_real_vout, "video-device", val2 );
}
b_embedded = var_GetBool( p_vout, "macosx-embedded" );
/* Find out on which screen to open the window */
- if( i_device <= 0 || i_device > (int)[o_screens count] )
- {
- /* No preference specified. Use the main screen */
+ o_screen = [NSScreen screenWithDisplayID: (CGDirectDisplayID)i_device];
+
+ if( !o_screen )
o_screen = [NSScreen mainScreen];
- i_device = [o_screens indexOfObject: o_screen];
- if( o_screen == [o_screens objectAtIndex: 0] )
- b_menubar_screen = VLC_TRUE;
- }
- else
- {
- i_device--;
- o_screen = [o_screens objectAtIndex: i_device];
- b_menubar_screen = ( i_device == 0 );
- }
+
+ if( o_screen == [NSScreen mainScreen] )
+ b_menubar_screen = VLC_TRUE;
if( p_vout->b_fullscreen )
{
defer: YES screen: o_screen];
if( b_black == VLC_TRUE )
- {
- CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
- CGDisplayFade( token, 0.5, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, true );
- CGReleaseDisplayFadeReservation( token );
- unsigned int i;
- for( i = 0 ; i < [o_screens count]; i++)
- {
- struct
- {
- CGDirectDisplayID displayID;
- CGGammaValue redMin, redMax, redGamma,
- greenMin, greenMax, greenGamma,
- blueMin, blueMax, blueGamma;
- } dispSettings;
- CGDisplayCount dspyCnt;
- CGPoint gPoint;
-
- if( i == (unsigned int)i_device ) continue;
-
- screen_rect = [[o_screens objectAtIndex: i] frame];
-
- gPoint.x = screen_rect.origin.x;
- gPoint.y = screen_rect.origin.y;
- CGGetDisplaysWithPoint( gPoint, 1, &(dispSettings.displayID), &dspyCnt);
- CGGetDisplayTransferByFormula(
- dispSettings.displayID,
- &dispSettings.redMin, &dispSettings.redMax, &dispSettings.redGamma,
- &dispSettings.greenMin, &dispSettings.greenMax, &dispSettings.greenGamma,
- &dispSettings.blueMin, &dispSettings.blueMax, &dispSettings.blueGamma );
- CGSetDisplayTransferByFormula(
- dispSettings.displayID,
- dispSettings.redMin, 0, dispSettings.redGamma,
- dispSettings.greenMin, 0, dispSettings.greenGamma,
- dispSettings.blueMin, 0, dispSettings.blueGamma );
- }
- }
+ [o_screen blackoutOtherScreens];
+
if( b_menubar_screen )
{
SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);