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>
13 * Felix K
\9fhne <fkuehne at videolan dot org>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
28 *****************************************************************************/
30 /*****************************************************************************
32 *****************************************************************************/
33 #include <errno.h> /* ENOMEM */
34 #include <stdlib.h> /* free() */
35 #include <string.h> /* strerror() */
37 /* BeginFullScreen, EndFullScreen */
38 #include <QuickTime/QuickTime.h>
46 /*****************************************************************************
47 * DeviceCallback: Callback triggered when the video-device variable is changed
48 *****************************************************************************/
49 int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
50 vlc_value_t old_val, vlc_value_t new_val, void *param )
53 vout_thread_t *p_vout = (vout_thread_t *)p_this;
55 msg_Dbg( p_vout, "set %d", new_val.i_int );
56 var_Create( p_vout->p_vlc, "video-device", VLC_VAR_INTEGER );
57 var_Set( p_vout->p_vlc, "video-device", new_val );
59 val.b_bool = VLC_TRUE;
60 var_Set( p_vout, "intf-change", val );
65 /*****************************************************************************
66 * VLCEmbeddedList implementation
67 *****************************************************************************/
68 @implementation VLCEmbeddedList
73 o_embedded_array = [NSMutableArray array];
81 for( i = 0; i < [o_embedded_array count]; i++ )
83 id o_vout_view = [o_embedded_array objectAtIndex: i];
84 if( ![o_vout_view isUsed] )
86 [o_vout_view setUsed: YES];
93 - (void)releaseEmbeddedVout: (id)o_vout_view
95 if( [o_embedded_array containsObject: o_vout_view] )
97 [o_vout_view setUsed: NO];
101 msg_Warn( VLCIntf, "cannot find Video Output");
105 - (void)addEmbeddedVout: (id)o_vout_view
107 if( ![o_embedded_array containsObject: o_vout_view] )
109 [o_embedded_array addObject: o_vout_view];
113 - (BOOL)windowContainsEmbedded: (id)o_window
115 /* if( ![[o_window className] isEqualToString: @"VLCWindow"] )
117 NSLog( @"We were not given a VLCWindow" );
119 return ([self getViewForWindow: o_window] == nil ? NO : YES );
122 - (id)getViewForWindow: (id)o_window
124 id o_enumerator = [o_embedded_array objectEnumerator];
125 id o_current_embedded;
127 while( (o_current_embedded = [o_enumerator nextObject]) )
129 if( [o_current_embedded getWindow] == o_window )
131 return o_current_embedded;
139 /*****************************************************************************
140 * VLCVoutView implementation
141 *****************************************************************************/
142 @implementation VLCVoutView
144 - (id)initWithFrame:(NSRect)frameRect
146 [super initWithFrame: frameRect];
149 s_frame = &frameRect;
156 - (BOOL)setVout: (vout_thread_t *) vout subView: (NSView *) view
157 frame: (NSRect *) frame
160 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
161 NSArray *o_screens = [NSScreen screens];
167 if( [o_screens count] <= 0 )
169 msg_Err( p_vout, "no OSX screens available" );
173 p_real_vout = [VLCVoutView getRealVout: p_vout];
175 /* Get the pref value when this is the first time, otherwise retrieve the device from the top level video-device var */
176 if( var_Type( p_real_vout->p_vlc, "video-device" ) == 0 )
178 i_device = var_GetInteger( p_vout, "macosx-vdev" );
182 i_device = var_GetInteger( p_real_vout->p_vlc, "video-device" );
185 /* Setup the menuitem for the multiple displays. */
186 if( var_Type( p_real_vout, "video-device" ) == 0 )
189 vlc_value_t val2, text;
192 var_Create( p_real_vout, "video-device", VLC_VAR_INTEGER |
194 text.psz_string = _("Video Device");
195 var_Change( p_real_vout, "video-device", VLC_VAR_SETTEXT, &text, NULL );
197 NSEnumerator * o_enumerator = [o_screens objectEnumerator];
200 text.psz_string = _("Default");
201 var_Change( p_real_vout, "video-device",
202 VLC_VAR_ADDCHOICE, &val2, &text );
203 var_Set( p_real_vout, "video-device", val2 );
205 while( (o_screen = [o_enumerator nextObject]) != NULL )
208 NSRect s_rect = [o_screen frame];
210 snprintf( psz_temp, sizeof(psz_temp)/sizeof(psz_temp[0])-1,
211 "%s %d (%dx%d)", _("Screen"), i,
212 (int)s_rect.size.width, (int)s_rect.size.height );
214 text.psz_string = psz_temp;
216 var_Change( p_real_vout, "video-device",
217 VLC_VAR_ADDCHOICE, &val2, &text );
220 var_Set( p_real_vout, "video-device", val2 );
225 var_AddCallback( p_real_vout, "video-device", DeviceCallback,
228 val2.b_bool = VLC_TRUE;
229 var_Set( p_real_vout, "intf-change", val2 );
232 /* Add the view. It's automatically resized to fit the window */
233 [self addSubview: o_view];
234 [self setAutoresizesSubviews: YES];
240 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize
242 [super resizeSubviewsWithOldSize: oldBoundsSize];
243 [o_view setFrameSize: [self frame].size];
248 [o_view removeFromSuperview];
258 NSMutableString * o_title = nil, * o_mrl = nil;
259 input_thread_t * p_input;
266 p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
268 if( p_input == NULL )
273 if( p_input->input.p_item->psz_name != NULL )
274 o_title = [NSMutableString stringWithUTF8String:
275 p_input->input.p_item->psz_name];
276 if( p_input->input.p_item->psz_uri != NULL )
277 o_mrl = [NSMutableString stringWithUTF8String:
278 p_input->input.p_item->psz_uri];
284 if( p_input->input.p_access && !strcmp( p_input->input.p_access->p_module->psz_shortname, "File" ) )
286 NSRange prefix_range = [o_mrl rangeOfString: @"file:"];
287 if( prefix_range.location != NSNotFound )
288 [o_mrl deleteCharactersInRange: prefix_range];
289 [o_window setRepresentedFilename: o_mrl];
291 [o_window setTitle: o_title];
295 [o_window setTitle: [NSString stringWithCString: VOUT_TITLE]];
297 vlc_object_release( p_input );
301 - (void)setOnTop:(BOOL)b_on_top
305 [o_window setLevel: NSStatusWindowLevel];
309 [o_window setLevel: NSNormalWindowLevel];
313 - (void)scaleWindowWithFactor: (float)factor
316 int i_corrected_height, i_corrected_width;
318 NSPoint topleftscreen;
320 if ( !p_vout->b_fullscreen )
324 topleftbase.y = [o_window frame].size.height;
325 topleftscreen = [o_window convertBaseToScreen: topleftbase];
327 if( p_vout->render.i_height * p_vout->render.i_aspect >
328 p_vout->render.i_width * VOUT_ASPECT_FACTOR )
330 i_corrected_width = p_vout->render.i_height * p_vout->render.i_aspect /
332 newsize.width = (int) ( i_corrected_width * factor );
333 newsize.height = (int) ( p_vout->render.i_height * factor );
337 i_corrected_height = p_vout->render.i_width * VOUT_ASPECT_FACTOR /
338 p_vout->render.i_aspect;
339 newsize.width = (int) ( p_vout->render.i_width * factor );
340 newsize.height = (int) ( i_corrected_height * factor );
343 /* Calculate the window's new size */
344 new_frame.size.width = [o_window frame].size.width -
345 [self frame].size.width + newsize.width;
346 new_frame.size.height = [o_window frame].size.height -
347 [self frame].size.height + newsize.height;
349 new_frame.origin.x = topleftscreen.x;
350 new_frame.origin.y = topleftscreen.y - new_frame.size.height;
352 [o_window setFrame: new_frame display: YES];
354 p_vout->i_changes |= VOUT_SIZE_CHANGE;
358 - (void)toggleFloatOnTop
362 if( !p_real_vout ) return;
363 if( var_Get( p_real_vout, "video-on-top", &val )>=0 && val.b_bool)
365 val.b_bool = VLC_FALSE;
369 val.b_bool = VLC_TRUE;
371 var_Set( p_real_vout, "video-on-top", val );
374 - (void)toggleFullscreen
377 if( !p_real_vout ) return;
378 var_Get( p_real_vout, "fullscreen", &val );
379 val.b_bool = !val.b_bool;
380 var_Set( p_real_vout, "fullscreen", val );
386 var_Get( p_real_vout, "fullscreen", &val );
387 return( val.b_bool );
392 vout_Control( p_real_vout, VOUT_SNAPSHOT );
397 /* Disable Screensaver */
398 UpdateSystemActivity( UsrActivity );
406 - (void)keyDown:(NSEvent *)o_event
410 unsigned int i_pressed_modifiers = 0;
413 i_pressed_modifiers = [o_event modifierFlags];
415 if( i_pressed_modifiers & NSShiftKeyMask )
416 val.i_int |= KEY_MODIFIER_SHIFT;
417 if( i_pressed_modifiers & NSControlKeyMask )
418 val.i_int |= KEY_MODIFIER_CTRL;
419 if( i_pressed_modifiers & NSAlternateKeyMask )
420 val.i_int |= KEY_MODIFIER_ALT;
421 if( i_pressed_modifiers & NSCommandKeyMask )
422 val.i_int |= KEY_MODIFIER_COMMAND;
424 key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
428 /* Escape should always get you out of fullscreen */
429 if( key == (unichar) 0x1b )
431 if( p_real_vout && [self isFullscreen] )
433 [self toggleFullscreen];
436 else if ( key == ' ' )
439 val.i_int = config_GetInt( p_vout, "key-play-pause" );
440 var_Set( p_vout->p_vlc, "key-pressed", val );
444 val.i_int |= CocoaKeyToVLC( key );
445 var_Set( p_vout->p_vlc, "key-pressed", val );
450 [super keyDown: o_event];
454 - (void)mouseDown:(NSEvent *)o_event
460 switch( [o_event type] )
462 case NSLeftMouseDown:
464 if( [o_event clickCount] <= 1 )
466 /* single clicking */
467 var_Get( p_vout, "mouse-button-down", &val );
469 var_Set( p_vout, "mouse-button-down", val );
473 /* multiple clicking */
474 [self toggleFullscreen];
478 case NSRightMouseDown:
480 msg_Dbg( p_vout, "received NSRightMouseDown (generic method)" );
481 [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
486 [super mouseDown: o_event];
492 - (void)otherMouseDown:(NSEvent *)o_event
498 switch( [o_event type] )
500 case NSOtherMouseDown:
502 var_Get( p_vout, "mouse-button-down", &val );
504 var_Set( p_vout, "mouse-button-down", val );
509 [super mouseDown: o_event];
515 - (void)rightMouseDown:(NSEvent *)o_event
519 switch( [o_event type] )
521 case NSRightMouseDown:
523 msg_Dbg( p_vout, "received NSRightMouseDown (specific method)" );
524 [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
529 [super mouseDown: o_event];
535 - (void)mouseUp:(NSEvent *)o_event
541 switch( [o_event type] )
546 b_val.b_bool = VLC_TRUE;
547 var_Set( p_vout, "mouse-clicked", b_val );
549 var_Get( p_vout, "mouse-button-down", &val );
551 var_Set( p_vout, "mouse-button-down", val );
556 [super mouseUp: o_event];
562 - (void)otherMouseUp:(NSEvent *)o_event
568 switch( [o_event type] )
572 var_Get( p_vout, "mouse-button-down", &val );
574 var_Set( p_vout, "mouse-button-down", val );
579 [super mouseUp: o_event];
585 - (void)rightMouseUp:(NSEvent *)o_event
589 switch( [o_event type] )
593 /* FIXME: this is the appropriate place, but we can't receive
594 * NSRightMouseDown some how */
595 msg_Dbg( p_vout, "received NSRightMouseUp" );
596 [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
601 [super mouseUp: o_event];
607 - (void)mouseDragged:(NSEvent *)o_event
609 [self mouseMoved: o_event];
612 - (void)otherMouseDragged:(NSEvent *)o_event
614 [self mouseMoved: o_event];
617 - (void)rightMouseDragged:(NSEvent *)o_event
619 [self mouseMoved: o_event];
622 - (void)mouseMoved:(NSEvent *)o_event
630 s_rect = [o_view bounds];
631 ml = [o_view convertPoint: [o_event locationInWindow] fromView: nil];
632 b_inside = [o_view mouse: ml inRect: s_rect];
637 unsigned int i_width, i_height, i_x, i_y;
639 vout_PlacePicture( p_vout, (unsigned int)s_rect.size.width,
640 (unsigned int)s_rect.size.height,
641 &i_x, &i_y, &i_width, &i_height );
643 val.i_int = ( ((int)ml.x) - i_x ) *
644 p_vout->render.i_width / i_width;
645 var_Set( p_vout, "mouse-x", val );
647 if( [[o_view className] isEqualToString: @"VLCGLView"] )
649 val.i_int = ( ((int)(s_rect.size.height - ml.y)) - i_y ) *
650 p_vout->render.i_height / i_height;
654 val.i_int = ( ((int)ml.y) - i_y ) *
655 p_vout->render.i_height / i_height;
657 var_Set( p_vout, "mouse-y", val );
659 val.b_bool = VLC_TRUE;
660 var_Set( p_vout, "mouse-moved", val );
663 [super mouseMoved: o_event];
666 - (BOOL)acceptsFirstResponder
671 - (BOOL)becomeFirstResponder
676 - (BOOL)resignFirstResponder
678 /* We need to stay the first responder or we'll miss some
683 /* Class methods used by the different vout modules */
685 + (vout_thread_t *)getRealVout: (vout_thread_t *)p_vout
687 /* p_real_vout: the vout we have to use to check for video-on-top
688 and a few other things. If we are the QuickTime output, it's us.
689 It we are the OpenGL provider, it is our parent. */
690 if( p_vout->i_object_type == VLC_OBJECT_OPENGL )
692 return (vout_thread_t *) p_vout->p_parent;
701 + (id)getVoutView: (vout_thread_t *)p_vout subView: (NSView *)view
702 frame: (NSRect *)s_frame
704 vlc_value_t value_drawable;
707 vout_thread_t * p_real_vout = [VLCVoutView getRealVout: p_vout];
709 var_Get( p_vout->p_vlc, "drawable", &value_drawable );
711 var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
712 var_Create( p_vout, "macosx-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
713 var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
714 var_Create( p_vout, "macosx-opaqueness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
715 var_Create( p_vout, "macosx-background", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
716 var_Create( p_vout, "macosx-black", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
717 var_Create( p_vout, "macosx-embedded", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
720 /* We only wait for NSApp to initialise if we're not embedded (as in the
721 * case of the Mozilla plugin). We can tell whether we're embedded or not
722 * by examining the "drawable" value: if it's zero, we're running in the
723 * main Mac intf; if it's non-zero, we're embedded. */
724 if( value_drawable.i_int == 0 )
726 /* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
727 for( i_timeout = 20 ; i_timeout-- ; )
731 msleep( INTF_IDLE_SLEEP );
737 /* No MacOS X intf, unable to communicate with MT */
738 msg_Err( p_vout, "no MacOS X interface present" );
743 if ( VLCIntf && !(p_vout->b_fullscreen) &&
744 !(var_GetBool( p_real_vout, "macosx-background" )) &&
745 var_GetBool( p_vout, "macosx-embedded") )
747 o_return = [[[VLCMain sharedInstance] getEmbeddedList]
753 /* No embedded vout is available */
754 if( o_return == nil )
757 bzero( &null_rect, sizeof( NSRect ) );
758 o_return = [[VLCDetachedVoutView alloc] initWithFrame: null_rect ];
760 [o_return setVout: p_vout subView: view frame: s_frame];
766 /*****************************************************************************
767 * VLCDetachedVoutView implementation
768 *****************************************************************************/
769 @implementation VLCDetachedVoutView
771 - (id)initWithFrame: (NSRect)frameRect
773 [super initWithFrame: frameRect];
774 i_time_mouse_last_moved = 0;
778 - (bool)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
779 frame: (NSRect *) s_arg_frame
781 BOOL b_return = [super setVout: p_arg_vout subView: view frame:s_arg_frame];
782 i_time_mouse_last_moved = mdate();
783 o_window = [[VLCWindow alloc] initWithVout: p_arg_vout view: self
786 [view setFrame: [self frame]];
788 if( var_GetBool( p_real_vout, "video-on-top" ) )
790 [o_window setLevel: NSStatusWindowLevel];
794 [o_window setAcceptsMouseMovedEvents: TRUE];
800 [o_window closeWindow];
801 [o_window setAcceptsMouseMovedEvents: NO];
802 i_time_mouse_last_moved = 0;
806 - (void)mouseMoved:(NSEvent *)o_event
808 i_time_mouse_last_moved = mdate();
809 [super mouseMoved: o_event];
812 - (void)hideMouse:(BOOL)b_hide
816 NSView *o_contents = [o_window contentView];
818 ml = [o_window convertScreenToBase:[NSEvent mouseLocation]];
819 ml = [o_contents convertPoint:ml fromView:nil];
820 b_inside = [o_contents mouse: ml inRect: [o_contents bounds]];
822 if( b_hide && b_inside )
824 [NSCursor setHiddenUntilMouseMoves: YES];
828 [NSCursor setHiddenUntilMouseMoves: NO];
835 if( p_vout->b_fullscreen )
837 if( mdate() - i_time_mouse_last_moved > 3000000 )
839 [self hideMouse: YES];
844 [self hideMouse: NO];
850 /*****************************************************************************
851 * VLCEmbeddedVoutView implementation
852 *****************************************************************************/
854 @implementation VLCEmbeddedVoutView
856 - (id)initWithFrame: (NSRect)frameRect
858 [super initWithFrame: frameRect];
860 [[[VLCMain sharedInstance] getEmbeddedList] addEmbeddedVout: self];
864 - (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
865 frame: (NSRect *) s_arg_frame
869 b_return = [super setVout: p_arg_vout subView: view frame: s_arg_frame];
872 o_window = [self window];
873 [o_window makeKeyAndOrderFront: self];
874 [o_window setAcceptsMouseMovedEvents: TRUE];
876 if( var_GetBool( p_real_vout, "video-on-top" ) )
878 [o_window setLevel: NSStatusWindowLevel];
881 [view setFrameSize: [self frame].size];
886 - (void)setUsed: (BOOL)b_new_used
899 [o_window setAcceptsMouseMovedEvents: NO];
900 [[[VLCMain sharedInstance] getEmbeddedList] releaseEmbeddedVout: self];
906 @implementation VLCDetachedEmbeddedVoutView
908 - (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
909 frame: (NSRect *) s_arg_frame
911 BOOL b_return = [super setVout: p_arg_vout subView: view frame: s_arg_frame];
915 [o_window setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
917 [self scaleWindowWithFactor: 1.0];
918 [o_window makeKeyAndOrderFront: self];
925 [o_window orderOut: self];
931 /*****************************************************************************
932 * VLCWindow implementation
933 *****************************************************************************/
934 @implementation VLCWindow
936 - (id) initWithVout: (vout_thread_t *) vout view: (VLCVoutView *) view
937 frame: (NSRect *) frame
943 [self performSelectorOnMainThread: @selector(initReal:)
944 withObject: NULL waitUntilDone: YES];
954 - (id)initReal: (id) sender
956 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
957 NSArray *o_screens = [NSScreen screens];
959 vlc_bool_t b_menubar_screen = VLC_FALSE;
962 b_init_ok = VLC_FALSE;
964 p_real_vout = [VLCVoutView getRealVout: p_vout];
965 i_device = var_GetInteger( p_real_vout->p_vlc, "video-device" );
966 b_black = var_GetBool( p_real_vout->p_vlc, "macosx-black" );
968 /* Find out on which screen to open the window */
969 if( i_device <= 0 || i_device > (int)[o_screens count] )
971 /* No preference specified. Use the main screen */
972 o_screen = [NSScreen mainScreen];
973 i_device = [o_screens indexOfObject: o_screen];
974 if( o_screen == [o_screens objectAtIndex: 0] )
975 b_menubar_screen = VLC_TRUE;
980 o_screen = [o_screens objectAtIndex: i_device];
981 b_menubar_screen = ( i_device == 0 );
984 if( p_vout->b_fullscreen )
986 CGDisplayFadeReservationToken token;
987 NSRect screen_rect = [o_screen frame];
988 screen_rect.origin.x = screen_rect.origin.y = 0;
990 /* Creates a window with size: screen_rect on o_screen */
991 [self initWithContentRect: screen_rect
992 styleMask: NSBorderlessWindowMask
993 backing: NSBackingStoreBuffered
994 defer: YES screen: o_screen];
996 if( var_GetBool( p_real_vout, "macosx-black" ) )
997 if( b_black == VLC_TRUE )
999 CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
1000 CGDisplayFade( token, 0.5, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, true );
1001 CGReleaseDisplayFadeReservation( token );
1003 for( i = 0 ; i < [o_screens count]; i++)
1007 CGDirectDisplayID displayID;
1008 CGGammaValue redMin, redMax, redGamma,
1009 greenMin, greenMax, greenGamma,
1010 blueMin, blueMax, blueGamma;
1012 CGDisplayCount dspyCnt;
1015 if( i == (unsigned int)i_device ) continue;
1017 screen_rect = [[o_screens objectAtIndex: i] frame];
1019 gPoint.x = screen_rect.origin.x;
1020 gPoint.y = screen_rect.origin.y;
1021 CGGetDisplaysWithPoint( gPoint, 1, &(dispSettings.displayID), &dspyCnt);
1022 CGGetDisplayTransferByFormula(
1023 dispSettings.displayID,
1024 &dispSettings.redMin, &dispSettings.redMax, &dispSettings.redGamma,
1025 &dispSettings.greenMin, &dispSettings.greenMax, &dispSettings.greenGamma,
1026 &dispSettings.blueMin, &dispSettings.blueMax, &dispSettings.blueGamma );
1027 CGSetDisplayTransferByFormula(
1028 dispSettings.displayID,
1029 dispSettings.redMin, 0, dispSettings.redGamma,
1030 dispSettings.greenMin, 0, dispSettings.greenGamma,
1031 dispSettings.blueMin, 0, dispSettings.blueGamma );
1034 if( b_menubar_screen )
1036 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
1038 if( b_black == VLC_TRUE )
1040 CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
1041 CGDisplayFade( token, 2 , kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, false );
1042 CGReleaseDisplayFadeReservation( token);
1045 else if( var_GetBool( p_real_vout, "macosx-background" ) )
1047 NSRect screen_rect = [o_screen frame];
1048 screen_rect.origin.x = screen_rect.origin.y = 0;
1050 /* Creates a window with size: screen_rect on o_screen */
1051 [self initWithContentRect: screen_rect
1052 styleMask: NSBorderlessWindowMask
1053 backing: NSBackingStoreBuffered
1054 defer: YES screen: o_screen];
1056 [self setLevel: CGWindowLevelForKey(kCGDesktopWindowLevelKey)];
1060 unsigned int i_stylemask = NSTitledWindowMask |
1061 NSMiniaturizableWindowMask |
1062 NSClosableWindowMask |
1063 NSResizableWindowMask;
1068 s_rect.size.width = p_vout->i_window_width;
1069 s_rect.size.height = p_vout->i_window_height;
1076 [self initWithContentRect: s_rect
1077 styleMask: i_stylemask
1078 backing: NSBackingStoreBuffered
1079 defer: YES screen: o_screen];
1081 [self setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
1089 [self makeKeyAndOrderFront: nil];
1090 [self setReleasedWhenClosed: YES];
1092 /* We'll catch mouse events */
1093 [self makeFirstResponder: o_view];
1095 /* Add the view. It's automatically resized to fit the window */
1096 [self setContentView: o_view];
1100 b_init_ok = VLC_TRUE;
1109 - (void) closeWindow
1111 /* XXX waitUntilDone = NO to avoid a possible deadlock when hitting
1113 [self setContentView: NULL];
1114 [self performSelectorOnMainThread: @selector(closeReal:)
1115 withObject: NULL waitUntilDone: NO];
1118 - (id) closeReal: (id) sender
1120 if( b_black == VLC_TRUE )
1122 CGDisplayFadeReservationToken token;
1123 CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
1124 CGDisplayFade( token, 2, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, false );
1125 CGReleaseDisplayFadeReservation( token);
1126 CGDisplayRestoreColorSyncSettings();
1128 SetSystemUIMode( kUIModeNormal, 0);
1138 - (BOOL)canBecomeKeyWindow
1143 /* Sometimes crashes VLC....
1144 - (BOOL)performKeyEquivalent:(NSEvent *)o_event
1146 return [[VLCMain sharedInstance] hasDefinedShortcutKey:o_event];
1149 /* This is actually the same as VLCControls::stop. */
1151 - (BOOL)windowShouldClose:(id)sender
1153 playlist_t * p_playlist = vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
1155 if( p_playlist == NULL )
1160 playlist_Stop( p_playlist );
1161 vlc_object_release( p_playlist );
1163 /* The window will be closed by the intf later. */