1 /*****************************************************************************
2 * vout.m: MacOS X video output module
3 *****************************************************************************
4 * Copyright (C) 2001-2006 the VideoLAN team
7 * Authors: Colin Delacroix <colin@zoy.org>
8 * Florian G. Pflug <fgp@phlo.org>
9 * Jon Lech Johansen <jon-vl@nanocrew.net>
10 * Derk-Jan Hartman <hartman at videolan dot org>
11 * Eric Petit <titer@m0k.org>
12 * Benjamin Pracht <bigben at videolan dot org>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27 *****************************************************************************/
29 /*****************************************************************************
31 *****************************************************************************/
32 #include <errno.h> /* ENOMEM */
33 #include <stdlib.h> /* free() */
34 #include <string.h> /* strerror() */
36 /* BeginFullScreen, EndFullScreen */
37 #include <QuickTime/QuickTime.h>
45 /*****************************************************************************
46 * DeviceCallback: Callback triggered when the video-device variable is changed
47 *****************************************************************************/
48 int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
49 vlc_value_t old_val, vlc_value_t new_val, void *param )
52 vout_thread_t *p_vout = (vout_thread_t *)p_this;
54 msg_Dbg( p_vout, "set %d", new_val.i_int );
55 var_Create( p_vout->p_vlc, "video-device", VLC_VAR_INTEGER );
56 var_Set( p_vout->p_vlc, "video-device", new_val );
58 val.b_bool = VLC_TRUE;
59 var_Set( p_vout, "intf-change", val );
64 /*****************************************************************************
65 * VLCEmbeddedList implementation
66 *****************************************************************************/
67 @implementation VLCEmbeddedList
72 o_embedded_array = [NSMutableArray array];
80 for( i = 0; i < [o_embedded_array count]; i++ )
82 id o_vout_view = [o_embedded_array objectAtIndex: i];
83 if( ![o_vout_view isUsed] )
85 [o_vout_view setUsed: YES];
92 - (void)releaseEmbeddedVout: (id)o_vout_view
94 if( [o_embedded_array containsObject: o_vout_view] )
96 [o_vout_view setUsed: NO];
100 msg_Warn( VLCIntf, "cannot find Video Output");
104 - (void)addEmbeddedVout: (id)o_vout_view
106 if( ![o_embedded_array containsObject: o_vout_view] )
108 [o_embedded_array addObject: o_vout_view];
112 - (BOOL)windowContainsEmbedded: (id)o_window
114 /* if( ![[o_window className] isEqualToString: @"VLCWindow"] )
116 NSLog( @"We were not given a VLCWindow" );
118 return ([self getViewForWindow: o_window] == nil ? NO : YES );
121 - (id)getViewForWindow: (id)o_window
123 id o_enumerator = [o_embedded_array objectEnumerator];
124 id o_current_embedded;
126 while( (o_current_embedded = [o_enumerator nextObject]) )
128 if( [o_current_embedded getWindow] == o_window )
130 return o_current_embedded;
138 /*****************************************************************************
139 * VLCVoutView implementation
140 *****************************************************************************/
141 @implementation VLCVoutView
143 - (id)initWithFrame:(NSRect)frameRect
145 [super initWithFrame: frameRect];
148 s_frame = &frameRect;
155 - (BOOL)setVout: (vout_thread_t *) vout subView: (NSView *) view
156 frame: (NSRect *) frame
159 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
160 NSArray *o_screens = [NSScreen screens];
166 if( [o_screens count] <= 0 )
168 msg_Err( p_vout, "no OSX screens available" );
172 p_real_vout = [VLCVoutView getRealVout: p_vout];
174 /* Get the pref value when this is the first time, otherwise retrieve the device from the top level video-device var */
175 if( var_Type( p_real_vout->p_vlc, "video-device" ) == 0 )
177 i_device = var_GetInteger( p_vout, "macosx-vdev" );
181 i_device = var_GetInteger( p_real_vout->p_vlc, "video-device" );
184 /* Setup the menuitem for the multiple displays. */
185 if( var_Type( p_real_vout, "video-device" ) == 0 )
188 vlc_value_t val2, text;
191 var_Create( p_real_vout, "video-device", VLC_VAR_INTEGER |
193 text.psz_string = _("Video Device");
194 var_Change( p_real_vout, "video-device", VLC_VAR_SETTEXT, &text, NULL );
196 NSEnumerator * o_enumerator = [o_screens objectEnumerator];
199 text.psz_string = _("Default");
200 var_Change( p_real_vout, "video-device",
201 VLC_VAR_ADDCHOICE, &val2, &text );
202 var_Set( p_real_vout, "video-device", val2 );
204 while( (o_screen = [o_enumerator nextObject]) != NULL )
207 NSRect s_rect = [o_screen frame];
209 snprintf( psz_temp, sizeof(psz_temp)/sizeof(psz_temp[0])-1,
210 "%s %d (%dx%d)", _("Screen"), i,
211 (int)s_rect.size.width, (int)s_rect.size.height );
213 text.psz_string = psz_temp;
215 var_Change( p_real_vout, "video-device",
216 VLC_VAR_ADDCHOICE, &val2, &text );
219 var_Set( p_real_vout, "video-device", val2 );
224 var_AddCallback( p_real_vout, "video-device", DeviceCallback,
227 val2.b_bool = VLC_TRUE;
228 var_Set( p_real_vout, "intf-change", val2 );
231 /* Add the view. It's automatically resized to fit the window */
232 [self addSubview: o_view];
233 [self setAutoresizesSubviews: YES];
239 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize
241 [super resizeSubviewsWithOldSize: oldBoundsSize];
242 [o_view setFrameSize: [self frame].size];
247 [o_view removeFromSuperview];
257 NSMutableString * o_title = nil, * o_mrl = nil;
258 input_thread_t * p_input;
265 p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
267 if( p_input == NULL )
272 if( p_input->input.p_item->psz_name != NULL )
273 o_title = [NSMutableString stringWithUTF8String:
274 p_input->input.p_item->psz_name];
275 if( p_input->input.p_item->psz_uri != NULL )
276 o_mrl = [NSMutableString stringWithUTF8String:
277 p_input->input.p_item->psz_uri];
283 if( p_input->input.p_access && !strcmp( p_input->input.p_access->p_module->psz_shortname, "File" ) )
285 NSRange prefix_range = [o_mrl rangeOfString: @"file:"];
286 if( prefix_range.location != NSNotFound )
287 [o_mrl deleteCharactersInRange: prefix_range];
288 [o_window setRepresentedFilename: o_mrl];
290 [o_window setTitle: o_title];
294 [o_window setTitle: [NSString stringWithCString: VOUT_TITLE]];
296 vlc_object_release( p_input );
300 - (void)setOnTop:(BOOL)b_on_top
304 [o_window setLevel: NSStatusWindowLevel];
308 [o_window setLevel: NSNormalWindowLevel];
312 - (void)scaleWindowWithFactor: (float)factor
315 int i_corrected_height, i_corrected_width;
317 NSPoint topleftscreen;
319 if ( !p_vout->b_fullscreen )
323 topleftbase.y = [o_window frame].size.height;
324 topleftscreen = [o_window convertBaseToScreen: topleftbase];
326 if( p_vout->render.i_height * p_vout->render.i_aspect >
327 p_vout->render.i_width * VOUT_ASPECT_FACTOR )
329 i_corrected_width = p_vout->render.i_height * p_vout->render.i_aspect /
331 newsize.width = (int) ( i_corrected_width * factor );
332 newsize.height = (int) ( p_vout->render.i_height * factor );
336 i_corrected_height = p_vout->render.i_width * VOUT_ASPECT_FACTOR /
337 p_vout->render.i_aspect;
338 newsize.width = (int) ( p_vout->render.i_width * factor );
339 newsize.height = (int) ( i_corrected_height * factor );
342 /* Calculate the window's new size */
343 new_frame.size.width = [o_window frame].size.width -
344 [self frame].size.width + newsize.width;
345 new_frame.size.height = [o_window frame].size.height -
346 [self frame].size.height + newsize.height;
348 new_frame.origin.x = topleftscreen.x;
349 new_frame.origin.y = topleftscreen.y - new_frame.size.height;
351 [o_window setFrame: new_frame display: YES];
353 p_vout->i_changes |= VOUT_SIZE_CHANGE;
357 - (void)toggleFloatOnTop
361 if( !p_real_vout ) return;
362 if( var_Get( p_real_vout, "video-on-top", &val )>=0 && val.b_bool)
364 val.b_bool = VLC_FALSE;
368 val.b_bool = VLC_TRUE;
370 var_Set( p_real_vout, "video-on-top", val );
373 - (void)toggleFullscreen
376 if( !p_real_vout ) return;
377 var_Get( p_real_vout, "fullscreen", &val );
378 val.b_bool = !val.b_bool;
379 var_Set( p_real_vout, "fullscreen", val );
385 var_Get( p_real_vout, "fullscreen", &val );
386 return( val.b_bool );
391 vout_Control( p_real_vout, VOUT_SNAPSHOT );
396 /* Disable Screensaver */
397 UpdateSystemActivity( UsrActivity );
405 - (void)keyDown:(NSEvent *)o_event
409 unsigned int i_pressed_modifiers = 0;
412 i_pressed_modifiers = [o_event modifierFlags];
414 if( i_pressed_modifiers & NSShiftKeyMask )
415 val.i_int |= KEY_MODIFIER_SHIFT;
416 if( i_pressed_modifiers & NSControlKeyMask )
417 val.i_int |= KEY_MODIFIER_CTRL;
418 if( i_pressed_modifiers & NSAlternateKeyMask )
419 val.i_int |= KEY_MODIFIER_ALT;
420 if( i_pressed_modifiers & NSCommandKeyMask )
421 val.i_int |= KEY_MODIFIER_COMMAND;
423 key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
427 /* Escape should always get you out of fullscreen */
428 if( key == (unichar) 0x1b )
430 if( p_real_vout && [self isFullscreen] )
432 [self toggleFullscreen];
435 else if ( key == ' ' )
438 val.i_int = config_GetInt( p_vout, "key-play-pause" );
439 var_Set( p_vout->p_vlc, "key-pressed", val );
443 val.i_int |= CocoaKeyToVLC( key );
444 var_Set( p_vout->p_vlc, "key-pressed", val );
449 [super keyDown: o_event];
453 - (void)mouseDown:(NSEvent *)o_event
459 switch( [o_event type] )
461 case NSLeftMouseDown:
463 if( [o_event clickCount] <= 1 )
465 /* single clicking */
466 var_Get( p_vout, "mouse-button-down", &val );
468 var_Set( p_vout, "mouse-button-down", val );
472 /* multiple clicking */
473 [self toggleFullscreen];
479 [super mouseDown: o_event];
485 - (void)otherMouseDown:(NSEvent *)o_event
491 switch( [o_event type] )
493 case NSOtherMouseDown:
495 var_Get( p_vout, "mouse-button-down", &val );
497 var_Set( p_vout, "mouse-button-down", val );
502 [super mouseDown: o_event];
508 - (void)rightMouseDown:(NSEvent *)o_event
514 switch( [o_event type] )
516 case NSRightMouseDown:
518 var_Get( p_vout, "mouse-button-down", &val );
520 var_Set( p_vout, "mouse-button-down", val );
525 [super mouseDown: o_event];
531 - (void)mouseUp:(NSEvent *)o_event
537 switch( [o_event type] )
542 b_val.b_bool = VLC_TRUE;
543 var_Set( p_vout, "mouse-clicked", b_val );
545 var_Get( p_vout, "mouse-button-down", &val );
547 var_Set( p_vout, "mouse-button-down", val );
552 [super mouseUp: o_event];
558 - (void)otherMouseUp:(NSEvent *)o_event
564 switch( [o_event type] )
568 var_Get( p_vout, "mouse-button-down", &val );
570 var_Set( p_vout, "mouse-button-down", val );
575 [super mouseUp: o_event];
581 - (void)rightMouseUp:(NSEvent *)o_event
587 switch( [o_event type] )
591 var_Get( p_vout, "mouse-button-down", &val );
593 var_Set( p_vout, "mouse-button-down", val );
598 [super mouseUp: o_event];
604 - (void)mouseDragged:(NSEvent *)o_event
606 [self mouseMoved: o_event];
609 - (void)otherMouseDragged:(NSEvent *)o_event
611 [self mouseMoved: o_event];
614 - (void)rightMouseDragged:(NSEvent *)o_event
616 [self mouseMoved: o_event];
619 - (void)mouseMoved:(NSEvent *)o_event
627 s_rect = [o_view bounds];
628 ml = [o_view convertPoint: [o_event locationInWindow] fromView: nil];
629 b_inside = [o_view mouse: ml inRect: s_rect];
634 unsigned int i_width, i_height, i_x, i_y;
636 vout_PlacePicture( p_vout, (unsigned int)s_rect.size.width,
637 (unsigned int)s_rect.size.height,
638 &i_x, &i_y, &i_width, &i_height );
640 val.i_int = ( ((int)ml.x) - i_x ) *
641 p_vout->render.i_width / i_width;
642 var_Set( p_vout, "mouse-x", val );
644 if( [[o_view className] isEqualToString: @"VLCGLView"] )
646 val.i_int = ( ((int)(s_rect.size.height - ml.y)) - i_y ) *
647 p_vout->render.i_height / i_height;
651 val.i_int = ( ((int)ml.y) - i_y ) *
652 p_vout->render.i_height / i_height;
654 var_Set( p_vout, "mouse-y", val );
656 val.b_bool = VLC_TRUE;
657 var_Set( p_vout, "mouse-moved", val );
660 [super mouseMoved: o_event];
663 - (BOOL)acceptsFirstResponder
668 - (BOOL)becomeFirstResponder
673 - (BOOL)resignFirstResponder
675 /* We need to stay the first responder or we'll miss some
680 /* Class methods used by the different vout modules */
682 + (vout_thread_t *)getRealVout: (vout_thread_t *)p_vout
684 /* p_real_vout: the vout we have to use to check for video-on-top
685 and a few other things. If we are the QuickTime output, it's us.
686 It we are the OpenGL provider, it is our parent. */
687 if( p_vout->i_object_type == VLC_OBJECT_OPENGL )
689 return (vout_thread_t *) p_vout->p_parent;
698 + (id)getVoutView: (vout_thread_t *)p_vout subView: (NSView *)view
699 frame: (NSRect *)s_frame
701 vlc_value_t value_drawable;
704 vout_thread_t * p_real_vout = [VLCVoutView getRealVout: p_vout];
706 var_Get( p_vout->p_vlc, "drawable", &value_drawable );
708 var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
709 var_Create( p_vout, "macosx-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
710 var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
711 var_Create( p_vout, "macosx-opaqueness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
712 var_Create( p_vout, "macosx-background", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
713 var_Create( p_vout, "macosx-black", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
714 var_Create( p_vout, "macosx-embedded", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
717 /* We only wait for NSApp to initialise if we're not embedded (as in the
718 * case of the Mozilla plugin). We can tell whether we're embedded or not
719 * by examining the "drawable" value: if it's zero, we're running in the
720 * main Mac intf; if it's non-zero, we're embedded. */
721 if( value_drawable.i_int == 0 )
723 /* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
724 for( i_timeout = 20 ; i_timeout-- ; )
728 msleep( INTF_IDLE_SLEEP );
734 /* No MacOS X intf, unable to communicate with MT */
735 msg_Err( p_vout, "no MacOS X interface present" );
740 if ( VLCIntf && !(p_vout->b_fullscreen) &&
741 !(var_GetBool( p_real_vout, "macosx-background" )) &&
742 var_GetBool( p_vout, "macosx-embedded") )
744 o_return = [[[VLCMain sharedInstance] getEmbeddedList]
750 /* No embedded vout is available */
751 if( o_return == nil )
754 bzero( &null_rect, sizeof( NSRect ) );
755 o_return = [[VLCDetachedVoutView alloc] initWithFrame: null_rect ];
757 [o_return setVout: p_vout subView: view frame: s_frame];
763 /*****************************************************************************
764 * VLCDetachedVoutView implementation
765 *****************************************************************************/
766 @implementation VLCDetachedVoutView
768 - (id)initWithFrame: (NSRect)frameRect
770 [super initWithFrame: frameRect];
771 i_time_mouse_last_moved = 0;
775 - (bool)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
776 frame: (NSRect *) s_arg_frame
778 BOOL b_return = [super setVout: p_arg_vout subView: view frame:s_arg_frame];
779 i_time_mouse_last_moved = mdate();
780 o_window = [[VLCWindow alloc] initWithVout: p_arg_vout view: self
783 [view setFrame: [self frame]];
785 if( var_GetBool( p_real_vout, "video-on-top" ) )
787 [o_window setLevel: NSStatusWindowLevel];
791 [o_window setAcceptsMouseMovedEvents: TRUE];
797 [o_window closeWindow];
798 [o_window setAcceptsMouseMovedEvents: NO];
799 i_time_mouse_last_moved = 0;
803 - (void)mouseMoved:(NSEvent *)o_event
805 i_time_mouse_last_moved = mdate();
806 [super mouseMoved: o_event];
809 - (void)hideMouse:(BOOL)b_hide
813 NSView *o_contents = [o_window contentView];
815 ml = [o_window convertScreenToBase:[NSEvent mouseLocation]];
816 ml = [o_contents convertPoint:ml fromView:nil];
817 b_inside = [o_contents mouse: ml inRect: [o_contents bounds]];
819 if( b_hide && b_inside )
821 [NSCursor setHiddenUntilMouseMoves: YES];
825 [NSCursor setHiddenUntilMouseMoves: NO];
832 if( p_vout->b_fullscreen )
834 if( mdate() - i_time_mouse_last_moved > 3000000 )
836 [self hideMouse: YES];
841 [self hideMouse: NO];
847 /*****************************************************************************
848 * VLCEmbeddedVoutView implementation
849 *****************************************************************************/
851 @implementation VLCEmbeddedVoutView
853 - (id)initWithFrame: (NSRect)frameRect
855 [super initWithFrame: frameRect];
857 [[[VLCMain sharedInstance] getEmbeddedList] addEmbeddedVout: self];
861 - (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
862 frame: (NSRect *) s_arg_frame
866 b_return = [super setVout: p_arg_vout subView: view frame: s_arg_frame];
869 o_window = [self window];
870 [o_window makeKeyAndOrderFront: self];
871 [o_window setAcceptsMouseMovedEvents: TRUE];
873 if( var_GetBool( p_real_vout, "video-on-top" ) )
875 [o_window setLevel: NSStatusWindowLevel];
878 [view setFrameSize: [self frame].size];
883 - (void)setUsed: (BOOL)b_new_used
896 [o_window setAcceptsMouseMovedEvents: NO];
897 [[[VLCMain sharedInstance] getEmbeddedList] releaseEmbeddedVout: self];
903 @implementation VLCDetachedEmbeddedVoutView
905 - (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
906 frame: (NSRect *) s_arg_frame
908 BOOL b_return = [super setVout: p_arg_vout subView: view frame: s_arg_frame];
912 [o_window setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
914 [self scaleWindowWithFactor: 1.0];
915 [o_window makeKeyAndOrderFront: self];
922 [o_window orderOut: self];
928 /*****************************************************************************
929 * VLCWindow implementation
930 *****************************************************************************/
931 @implementation VLCWindow
933 - (id) initWithVout: (vout_thread_t *) vout view: (VLCVoutView *) view
934 frame: (NSRect *) frame
940 [self performSelectorOnMainThread: @selector(initReal:)
941 withObject: NULL waitUntilDone: YES];
951 - (id)initReal: (id) sender
953 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
954 NSArray *o_screens = [NSScreen screens];
956 vlc_bool_t b_menubar_screen = VLC_FALSE;
959 b_init_ok = VLC_FALSE;
961 p_real_vout = [VLCVoutView getRealVout: p_vout];
962 i_device = var_GetInteger( p_real_vout->p_vlc, "video-device" );
963 b_black = var_GetBool( p_real_vout->p_vlc, "macosx-black" );
965 /* Find out on which screen to open the window */
966 if( i_device <= 0 || i_device > (int)[o_screens count] )
968 /* No preference specified. Use the main screen */
969 o_screen = [NSScreen mainScreen];
970 i_device = [o_screens indexOfObject: o_screen];
971 if( o_screen == [o_screens objectAtIndex: 0] )
972 b_menubar_screen = VLC_TRUE;
977 o_screen = [o_screens objectAtIndex: i_device];
978 b_menubar_screen = ( i_device == 0 );
981 if( p_vout->b_fullscreen )
983 CGDisplayFadeReservationToken token;
984 NSRect screen_rect = [o_screen frame];
985 screen_rect.origin.x = screen_rect.origin.y = 0;
987 /* Creates a window with size: screen_rect on o_screen */
988 [self initWithContentRect: screen_rect
989 styleMask: NSBorderlessWindowMask
990 backing: NSBackingStoreBuffered
991 defer: YES screen: o_screen];
993 if( var_GetBool( p_real_vout, "macosx-black" ) )
994 if( b_black == VLC_TRUE )
996 CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
997 CGDisplayFade( token, 0.5, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, true );
998 CGReleaseDisplayFadeReservation( token );
1000 for( i = 0 ; i < [o_screens count]; i++)
1004 CGDirectDisplayID displayID;
1005 CGGammaValue redMin, redMax, redGamma,
1006 greenMin, greenMax, greenGamma,
1007 blueMin, blueMax, blueGamma;
1009 CGDisplayCount dspyCnt;
1012 if( i == (unsigned int)i_device ) continue;
1014 screen_rect = [[o_screens objectAtIndex: i] frame];
1016 gPoint.x = screen_rect.origin.x;
1017 gPoint.y = screen_rect.origin.y;
1018 CGGetDisplaysWithPoint( gPoint, 1, &(dispSettings.displayID), &dspyCnt);
1019 CGGetDisplayTransferByFormula(
1020 dispSettings.displayID,
1021 &dispSettings.redMin, &dispSettings.redMax, &dispSettings.redGamma,
1022 &dispSettings.greenMin, &dispSettings.greenMax, &dispSettings.greenGamma,
1023 &dispSettings.blueMin, &dispSettings.blueMax, &dispSettings.blueGamma );
1024 CGSetDisplayTransferByFormula(
1025 dispSettings.displayID,
1026 dispSettings.redMin, 0, dispSettings.redGamma,
1027 dispSettings.greenMin, 0, dispSettings.greenGamma,
1028 dispSettings.blueMin, 0, dispSettings.blueGamma );
1031 if( b_menubar_screen )
1033 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
1035 if( b_black == VLC_TRUE )
1037 CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
1038 CGDisplayFade( token, 2 , kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, false );
1039 CGReleaseDisplayFadeReservation( token);
1042 else if( var_GetBool( p_real_vout, "macosx-background" ) )
1044 NSRect screen_rect = [o_screen frame];
1045 screen_rect.origin.x = screen_rect.origin.y = 0;
1047 /* Creates a window with size: screen_rect on o_screen */
1048 [self initWithContentRect: screen_rect
1049 styleMask: NSBorderlessWindowMask
1050 backing: NSBackingStoreBuffered
1051 defer: YES screen: o_screen];
1053 [self setLevel: CGWindowLevelForKey(kCGDesktopWindowLevelKey)];
1057 unsigned int i_stylemask = NSTitledWindowMask |
1058 NSMiniaturizableWindowMask |
1059 NSClosableWindowMask |
1060 NSResizableWindowMask;
1065 s_rect.size.width = p_vout->i_window_width;
1066 s_rect.size.height = p_vout->i_window_height;
1073 [self initWithContentRect: s_rect
1074 styleMask: i_stylemask
1075 backing: NSBackingStoreBuffered
1076 defer: YES screen: o_screen];
1078 [self setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
1086 [self makeKeyAndOrderFront: nil];
1087 [self setReleasedWhenClosed: YES];
1089 /* We'll catch mouse events */
1090 [self makeFirstResponder: o_view];
1092 /* Add the view. It's automatically resized to fit the window */
1093 [self setContentView: o_view];
1097 b_init_ok = VLC_TRUE;
1106 - (void) closeWindow
1108 /* XXX waitUntilDone = NO to avoid a possible deadlock when hitting
1110 [self setContentView: NULL];
1111 [self performSelectorOnMainThread: @selector(closeReal:)
1112 withObject: NULL waitUntilDone: NO];
1115 - (id) closeReal: (id) sender
1117 if( b_black == VLC_TRUE )
1119 CGDisplayFadeReservationToken token;
1120 CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
1121 CGDisplayFade( token, 2, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, false );
1122 CGReleaseDisplayFadeReservation( token);
1123 CGDisplayRestoreColorSyncSettings();
1125 SetSystemUIMode( kUIModeNormal, 0);
1135 - (BOOL)canBecomeKeyWindow
1140 /* Sometimes crashes VLC....
1141 - (BOOL)performKeyEquivalent:(NSEvent *)o_event
1143 return [[VLCMain sharedInstance] hasDefinedShortcutKey:o_event];
1146 /* This is actually the same as VLCControls::stop. */
1148 - (BOOL)windowShouldClose:(id)sender
1150 playlist_t * p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
1152 if( p_playlist == NULL )
1157 playlist_Stop( p_playlist );
1158 vlc_object_release( p_playlist );
1160 /* The window will be closed by the intf later. */