1 /*****************************************************************************
2 * vout.m: MacOS X video output module
3 *****************************************************************************
4 * Copyright (C) 2001-2008 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 Paul Kühne <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() */
37 /* BeginFullScreen, EndFullScreen */
38 #include <QuickTime/QuickTime.h>
46 #import "embeddedwindow.h"
48 /*****************************************************************************
49 * DeviceCallback: Callback triggered when the video-device variable is changed
50 *****************************************************************************/
51 int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
52 vlc_value_t old_val, vlc_value_t new_val, void *param )
55 vout_thread_t *p_vout = (vout_thread_t *)p_this;
57 msg_Dbg( p_vout, "set %d", new_val.i_int );
58 var_Create( p_vout->p_libvlc, "video-device", VLC_VAR_INTEGER );
59 var_Set( p_vout->p_libvlc, "video-device", new_val );
62 var_Set( p_vout, "intf-change", val );
67 /*****************************************************************************
68 * VLCEmbeddedList implementation
69 *****************************************************************************/
70 @implementation VLCEmbeddedList
75 o_embedded_array = [NSMutableArray array];
83 for( i = 0; i < [o_embedded_array count]; i++ )
85 id o_vout_view = [o_embedded_array objectAtIndex: i];
86 if( ![o_vout_view isUsed] )
88 [o_vout_view setUsed: YES];
95 - (void)releaseEmbeddedVout: (id)o_vout_view
97 if( [o_embedded_array containsObject: o_vout_view] )
99 [o_vout_view setUsed: NO];
103 msg_Warn( VLCIntf, "cannot find Video Output");
107 - (void)addEmbeddedVout: (id)o_vout_view
109 if( ![o_embedded_array containsObject: o_vout_view] )
111 [o_embedded_array addObject: o_vout_view];
115 - (BOOL)windowContainsEmbedded: (id)o_window
117 /* if( ![[o_window className] isEqualToString: @"VLCVoutWindow"] )
119 NSLog( @"We were not given a VLCVoutWindow" );
121 return ([self getViewForWindow: o_window] == nil ? NO : YES );
124 - (id)getViewForWindow: (id)o_window
126 id o_enumerator = [o_embedded_array objectEnumerator];
127 id o_current_embedded;
129 while( (o_current_embedded = [o_enumerator nextObject]) )
131 if( [o_current_embedded getWindow] == o_window )
133 return o_current_embedded;
141 /*****************************************************************************
142 * VLCVoutView implementation
143 *****************************************************************************/
144 @implementation VLCVoutView
146 - (id)initWithFrame: (NSRect)frameRect
148 [super initWithFrame: frameRect];
151 s_frame = &frameRect;
158 - (BOOL)setVout: (vout_thread_t *) vout
159 subView: (NSView *) view
160 frame: (NSRect *) frame
163 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
164 NSArray *o_screens = [NSScreen screens];
170 if( [o_screens count] <= 0 )
172 msg_Err( p_vout, "no OSX screens available" );
176 p_real_vout = [VLCVoutView getRealVout: p_vout];
178 /* Get the pref value when this is the first time, otherwise retrieve the device from the top level video-device var */
179 if( var_Type( p_real_vout->p_libvlc, "video-device" ) == 0 )
181 i_device = var_GetInteger( p_vout, "macosx-vdev" );
185 i_device = var_GetInteger( p_real_vout->p_libvlc, "video-device" );
188 /* Setup the menuitem for the multiple displays. */
189 if( var_Type( p_real_vout, "video-device" ) == 0 )
192 vlc_value_t val2, text;
195 var_Create( p_real_vout, "video-device", VLC_VAR_INTEGER |
197 text.psz_string = _("Fullscreen Video Device");
198 var_Change( p_real_vout, "video-device", VLC_VAR_SETTEXT, &text, NULL );
200 NSEnumerator * o_enumerator = [o_screens objectEnumerator];
203 text.psz_string = _("Default");
204 var_Change( p_real_vout, "video-device",
205 VLC_VAR_ADDCHOICE, &val2, &text );
206 var_Set( p_real_vout, "video-device", val2 );
208 while( (o_screen = [o_enumerator nextObject]) != NULL )
211 NSRect s_rect = [o_screen frame];
213 snprintf( psz_temp, sizeof(psz_temp)/sizeof(psz_temp[0])-1,
214 "%s %d (%dx%d)", _("Screen"), i,
215 (int)s_rect.size.width, (int)s_rect.size.height );
217 text.psz_string = psz_temp;
218 val2.i_int = (int)[o_screen displayID];
219 var_Change( p_real_vout, "video-device",
220 VLC_VAR_ADDCHOICE, &val2, &text );
221 if( (int)[o_screen displayID] == i_device )
223 var_Set( p_real_vout, "video-device", val2 );
228 var_AddCallback( p_real_vout, "video-device", DeviceCallback,
232 var_Set( p_real_vout, "intf-change", val2 );
235 /* Add the view. It's automatically resized to fit the window */
236 [self addSubview: o_view];
237 [self setAutoresizesSubviews: YES];
243 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize
245 [super resizeSubviewsWithOldSize: oldBoundsSize];
246 [o_view setFrameSize: [self frame].size];
249 - (void)drawRect:(NSRect)rect
251 /* When there is no subview we draw a black background */
253 [[NSColor blackColor] set];
260 [[[[VLCMain sharedInstance] getControls] getFSPanel] fadeOut];
262 /* Make sure we don't see a white flash */
263 [[self window] disableScreenUpdatesUntilFlush];
264 [o_view removeFromSuperview];
274 NSString * o_title = nil;
275 NSMutableString * o_mrl = nil;
276 input_thread_t * p_input;
279 if( !p_vout ) return;
281 p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT );
283 if( !p_input ) return;
285 input_item_t * p_item = input_GetItem( p_input );
287 psz_title = input_item_GetNowPlaying ( p_item );
289 psz_title = input_item_GetName( p_item );
292 o_title = [NSString stringWithUTF8String: psz_title];
294 char *psz_uri = input_item_GetURI( p_item );
296 o_mrl = [NSMutableString stringWithUTF8String: psz_uri];
306 /* FIXME once psz_access is exported, we could check if we are
307 * reading from a file in a smarter way. */
309 NSRange prefix_range = [o_mrl rangeOfString: @"file:"];
310 if( prefix_range.location != NSNotFound )
311 [o_mrl deleteCharactersInRange: prefix_range];
313 if( [o_mrl characterAtIndex:0] == '/' )
315 /* it's a local file */
316 [o_window setRepresentedFilename: o_mrl];
320 /* it's from the network or somewhere else,
321 * we clear the previous path */
322 [o_window setRepresentedFilename: @""];
324 [o_window setTitle: o_title];
328 [o_window setTitle: [NSString stringWithUTF8String: VOUT_TITLE]];
330 vlc_object_release( p_input );
334 - (void)setOnTop:(BOOL)b_on_top
338 [o_window setLevel: NSStatusWindowLevel];
342 [o_window setLevel: NSNormalWindowLevel];
346 - (NSSize)voutSizeForFactor: (float)factor
348 int i_corrected_height, i_corrected_width;
351 if( p_vout->render.i_height * p_vout->render.i_aspect >
352 p_vout->render.i_width * VOUT_ASPECT_FACTOR )
354 i_corrected_width = p_vout->render.i_height * p_vout->render.i_aspect /
356 newsize.width = (int) ( i_corrected_width * factor );
357 newsize.height = (int) ( p_vout->render.i_height * factor );
361 i_corrected_height = p_vout->render.i_width * VOUT_ASPECT_FACTOR /
362 p_vout->render.i_aspect;
363 newsize.width = (int) ( p_vout->render.i_width * factor );
364 newsize.height = (int) ( i_corrected_height * factor );
370 - (void)scaleWindowWithFactor: (float)factor animate: (BOOL)animate
372 if ( !p_vout->b_fullscreen )
376 NSPoint topleftscreen;
380 topleftbase.y = [o_window frame].size.height;
381 topleftscreen = [o_window convertBaseToScreen: topleftbase];
383 newsize = [self voutSizeForFactor:factor];
385 /* In fullscreen mode we need to use a view that is different from
386 * ourselves, with the VLCEmbeddedWindow */
387 if([o_window isKindOfClass:[VLCEmbeddedWindow class]])
388 mainView = [o_window mainView];
392 /* Calculate the window's new size */
393 new_frame.size.width = [o_window frame].size.width -
394 [mainView frame].size.width + newsize.width;
395 new_frame.size.height = [o_window frame].size.height -
396 [mainView frame].size.height + newsize.height;
398 new_frame.origin.x = topleftscreen.x;
399 new_frame.origin.y = topleftscreen.y - new_frame.size.height;
401 [o_window setFrame:new_frame display:animate animate:animate];
402 p_vout->i_changes |= VOUT_SIZE_CHANGE;
406 - (void)toggleFloatOnTop
410 if( !p_real_vout ) return;
411 if( var_Get( p_real_vout, "video-on-top", &val )>=0 && val.b_bool)
419 var_Set( p_real_vout, "video-on-top", val );
422 - (void)toggleFullscreen
425 if( !p_real_vout ) return;
426 var_Get( p_real_vout, "fullscreen", &val );
427 val.b_bool = !val.b_bool;
428 var_Set( p_real_vout, "fullscreen", val );
434 if( !p_real_vout ) return NO;
435 var_Get( p_real_vout, "fullscreen", &val );
436 return( val.b_bool );
441 vout_Control( p_real_vout, VOUT_SNAPSHOT );
446 /* Disable Screensaver, when we're playing something, but allow it on pause */
447 if( !VLCIntf || !VLCIntf->p_sys || !VLCIntf->p_sys->i_play_status )
450 if( VLCIntf->p_sys->i_play_status == PLAYING_S )
451 UpdateSystemActivity( UsrActivity );
459 - (void)scrollWheel:(NSEvent *)theEvent
461 VLCControls * o_controls = (VLCControls *)[[NSApp delegate] getControls];
462 [o_controls scrollWheel: theEvent];
465 - (void)keyDown:(NSEvent *)o_event
469 unsigned int i_pressed_modifiers = 0;
472 i_pressed_modifiers = [o_event modifierFlags];
474 if( i_pressed_modifiers & NSShiftKeyMask )
475 val.i_int |= KEY_MODIFIER_SHIFT;
476 if( i_pressed_modifiers & NSControlKeyMask )
477 val.i_int |= KEY_MODIFIER_CTRL;
478 if( i_pressed_modifiers & NSAlternateKeyMask )
479 val.i_int |= KEY_MODIFIER_ALT;
480 if( i_pressed_modifiers & NSCommandKeyMask )
481 val.i_int |= KEY_MODIFIER_COMMAND;
483 key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
487 /* Escape should always get you out of fullscreen */
488 if( key == (unichar) 0x1b )
490 if( p_real_vout && [self isFullscreen] )
492 [self toggleFullscreen];
495 else if ( key == ' ' )
498 val.i_int = config_GetInt( p_vout, "key-play-pause" );
499 var_Set( p_vout->p_libvlc, "key-pressed", val );
503 val.i_int |= CocoaKeyToVLC( key );
504 var_Set( p_vout->p_libvlc, "key-pressed", val );
509 [super keyDown: o_event];
513 - (void)mouseDown:(NSEvent *)o_event
518 if( ( [o_event type] == NSLeftMouseDown ) &&
519 ( ! ( [o_event modifierFlags] & NSControlKeyMask ) ) )
521 if( [o_event clickCount] <= 1 )
523 /* single clicking */
524 var_Get( p_vout, "mouse-button-down", &val );
526 var_Set( p_vout, "mouse-button-down", val );
530 /* multiple clicking */
531 [self toggleFullscreen];
534 else if( ( [o_event type] == NSRightMouseDown ) ||
535 ( ( [o_event type] == NSLeftMouseDown ) &&
536 ( [o_event modifierFlags] & NSControlKeyMask ) ) )
538 msg_Dbg( p_vout, "received NSRightMouseDown (generic method) or Ctrl clic" );
539 [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
543 [super mouseDown: o_event];
546 - (void)otherMouseDown:(NSEvent *)o_event
550 if( p_vout && [o_event type] == NSOtherMouseDown )
552 var_Get( p_vout, "mouse-button-down", &val );
554 var_Set( p_vout, "mouse-button-down", val );
557 [super mouseDown: o_event];
560 - (void)rightMouseDown:(NSEvent *)o_event
562 if( p_vout && [o_event type] == NSRightMouseDown )
564 msg_Dbg( p_vout, "received NSRightMouseDown (specific method)" );
565 [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
568 [super mouseDown: o_event];
571 - (void)mouseUp:(NSEvent *)o_event
575 if( p_vout && [o_event type] == NSLeftMouseUp )
579 var_Set( p_vout, "mouse-clicked", b_val );
581 var_Get( p_vout, "mouse-button-down", &val );
583 var_Set( p_vout, "mouse-button-down", val );
586 [super mouseUp: o_event];
589 - (void)otherMouseUp:(NSEvent *)o_event
593 if( p_vout && [o_event type] == NSOtherMouseUp )
595 var_Get( p_vout, "mouse-button-down", &val );
597 var_Set( p_vout, "mouse-button-down", val );
600 [super mouseUp: o_event];
603 - (void)rightMouseUp:(NSEvent *)o_event
605 if( p_vout && [o_event type] == NSRightMouseUp )
607 /* FIXME: this isn't the appropriate place, but we can't receive
608 * NSRightMouseDown some how */
609 msg_Dbg( p_vout, "received NSRightMouseUp" );
610 [NSMenu popUpContextMenu: [[VLCMain sharedInstance] getVoutMenu] withEvent: o_event forView: [[[VLCMain sharedInstance] getControls] getVoutView]];
613 [super mouseUp: o_event];
616 - (void)mouseDragged:(NSEvent *)o_event
618 [self mouseMoved: o_event];
621 - (void)otherMouseDragged:(NSEvent *)o_event
623 [self mouseMoved: o_event];
626 - (void)rightMouseDragged:(NSEvent *)o_event
628 [self mouseMoved: o_event];
631 - (void)mouseMoved:(NSEvent *)o_event
639 s_rect = [o_view bounds];
640 ml = [o_view convertPoint: [o_event locationInWindow] fromView: nil];
641 b_inside = [o_view mouse: ml inRect: s_rect];
646 unsigned int i_width, i_height, i_x, i_y;
648 vout_PlacePicture( p_vout, (unsigned int)s_rect.size.width,
649 (unsigned int)s_rect.size.height,
650 &i_x, &i_y, &i_width, &i_height );
652 val.i_int = ( ((int)ml.x) - i_x ) *
653 p_vout->render.i_width / i_width;
654 var_Set( p_vout, "mouse-x", val );
656 if( [[o_view className] isEqualToString: @"VLCGLView"] )
658 val.i_int = ( ((int)(s_rect.size.height - ml.y)) - i_y ) *
659 p_vout->render.i_height / i_height;
663 val.i_int = ( ((int)ml.y) - i_y ) *
664 p_vout->render.i_height / i_height;
666 var_Set( p_vout, "mouse-y", val );
669 var_Set( p_vout, "mouse-moved", val );
671 if( [self isFullscreen] )
672 [[[[VLCMain sharedInstance] getControls] getFSPanel] fadeIn];
675 [super mouseMoved: o_event];
678 - (BOOL)acceptsFirstResponder
683 - (BOOL)becomeFirstResponder
688 - (BOOL)resignFirstResponder
690 /* We need to stay the first responder or we'll miss some
695 /* Class methods used by the different vout modules */
697 + (vout_thread_t *)getRealVout: (vout_thread_t *)p_vout
699 /* p_real_vout: the vout we have to use to check for video-on-top
700 and a few other things. If we are the QuickTime output, it's us.
701 It we are the OpenGL provider, it is our parent. */
702 if( p_vout->i_object_type == VLC_OBJECT_OPENGL )
704 return (vout_thread_t *) p_vout->p_parent;
713 + (id)getVoutView: (vout_thread_t *)p_vout subView: (NSView *)view
714 frame: (NSRect *)s_frame
716 vlc_value_t value_drawable;
720 var_Get( p_vout->p_libvlc, "drawable", &value_drawable );
722 var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
723 var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
724 var_Create( p_vout, "macosx-opaqueness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
725 var_Create( p_vout, "macosx-background", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
726 var_Create( p_vout, "macosx-black", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
727 var_Create( p_vout, "embedded-video", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
729 /* We only wait for NSApp to initialise if we're not embedded (as in the
730 * case of the Mozilla plugin). We can tell whether we're embedded or not
731 * by examining the "drawable" value: if it's zero, we're running in the
732 * main Mac intf; if it's non-zero, we're embedded. */
733 if( value_drawable.i_int == 0 )
735 /* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
736 for( i_timeout = 20 ; i_timeout-- ; )
740 msleep( INTF_IDLE_SLEEP );
746 /* No MacOS X intf, unable to communicate with MT */
747 msg_Err( p_vout, "no MacOS X interface present" );
752 if ( VLCIntf && !(p_vout->b_fullscreen) &&
753 !(var_GetBool( p_vout, "macosx-background" )) &&
754 var_GetBool( p_vout, "embedded-video") )
756 o_return = [[[VLCMain sharedInstance] getEmbeddedList]
762 /* No embedded vout is available */
763 if( o_return == nil )
766 bzero( &null_rect, sizeof( NSRect ) );
767 o_return = [[VLCDetachedVoutView alloc] initWithFrame: null_rect ];
769 [o_return setVout: p_vout subView: view frame: s_frame];
773 - (void)enterFullscreen
775 /* Save the settings for next playing item */
776 playlist_t * p_playlist = pl_Yield( p_real_vout );
777 var_SetBool( p_playlist, "fullscreen", true );
778 pl_Release( p_real_vout );
781 - (void)leaveFullscreen
783 /* Save the settings for next playing item */
784 playlist_t * p_playlist = pl_Yield( p_real_vout );
785 var_SetBool( p_playlist, "fullscreen", false );
786 pl_Release( p_real_vout );
791 /*****************************************************************************
792 * VLCDetachedVoutView implementation
793 *****************************************************************************/
794 @implementation VLCDetachedVoutView
796 - (id)initWithFrame: (NSRect)frameRect
798 [super initWithFrame: frameRect];
799 i_time_mouse_last_moved = 0;
803 - (BOOL)mouseDownCanMoveWindow
808 - (bool)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
809 frame: (NSRect *) s_arg_frame
811 BOOL b_return = [super setVout: p_arg_vout subView: view frame:s_arg_frame];
812 i_time_mouse_last_moved = mdate();
813 o_window = [[VLCVoutWindow alloc] initWithVout: p_arg_vout view: self
817 if([self isFullscreen])
818 [o_window performSelectorOnMainThread: @selector(enterFullscreen) withObject: NULL waitUntilDone: YES];
820 [view setFrame: [self frame]];
827 [o_window performSelectorOnMainThread: @selector(close) withObject: NULL waitUntilDone: YES];
828 i_time_mouse_last_moved = 0;
832 - (void)mouseMoved:(NSEvent *)o_event
834 i_time_mouse_last_moved = mdate();
835 [super mouseMoved: o_event];
838 - (void)hideMouse:(BOOL)b_hide
842 NSView *o_contents = [o_window contentView];
844 ml = [o_window convertScreenToBase:[NSEvent mouseLocation]];
845 ml = [o_contents convertPoint:ml fromView:nil];
846 b_inside = [o_contents mouse: ml inRect: [o_contents bounds]];
848 if( b_hide && b_inside )
850 [NSCursor setHiddenUntilMouseMoves: YES];
854 [NSCursor setHiddenUntilMouseMoves: NO];
860 /* Dooh, why do we spend processor time doing this kind of stuff? */
862 unsigned int i_mouse_hide_timeout =
863 var_CreateGetInteger(p_vout, "mouse-hide-timeout") * 1000;
865 if( i_mouse_hide_timeout < 100000 )
866 i_mouse_hide_timeout = 100000;
867 if( p_vout->b_fullscreen )
869 if( mdate() - i_time_mouse_last_moved > i_mouse_hide_timeout )
871 i_time_mouse_last_moved = mdate();
872 [self hideMouse: YES];
877 [self hideMouse: NO];
882 - (void)enterFullscreen
884 [o_window performSelectorOnMainThread: @selector(enterFullscreen) withObject: NULL waitUntilDone: NO];
885 [super enterFullscreen];
889 - (void)leaveFullscreen
891 [o_window performSelectorOnMainThread: @selector(leaveFullscreen) withObject: NULL waitUntilDone: NO];
892 [super leaveFullscreen];
896 - (void)scaleWindowWithFactor: (float)factor animate: (BOOL)animate
898 if( p_vout->b_fullscreen )
900 [o_window setMovableByWindowBackground: NO];
901 [super scaleWindowWithFactor: factor animate: animate];
902 [o_window setMovableByWindowBackground: YES];
906 /*****************************************************************************
907 * VLCEmbeddedVoutView implementation
908 *****************************************************************************/
910 @implementation VLCEmbeddedVoutView
914 o_embeddedwindow = [self window];
917 - (BOOL)mouseDownCanMoveWindow
922 - (id)initWithFrame: (NSRect)frameRect
924 if(self = [super initWithFrame: frameRect])
927 [[[VLCMain sharedInstance] getEmbeddedList] addEmbeddedVout: self];
928 o_embeddedwindow = nil; /* Filled later on in -awakeFromNib */
933 - (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
934 frame: (NSRect *)s_arg_frame
938 [NSObject cancelPreviousPerformRequestsWithTarget:o_window];
940 b_return = [super setVout: p_arg_vout subView: view frame: s_arg_frame];
943 o_window = [self window];
945 [o_window setAcceptsMouseMovedEvents: TRUE];
947 if( var_CreateGetBool( p_real_vout, "video-on-top" ) )
949 [o_window setLevel: NSStatusWindowLevel];
952 [view setFrameSize: [self frame].size];
955 /* o_window needs to point to our o_embeddedwindow, super might have set it
956 * to the fullscreen window that o_embeddedwindow setups during fullscreen */
957 o_window = o_embeddedwindow;
961 [o_window lockFullscreenAnimation];
963 [o_window setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
967 [NSObject cancelPreviousPerformRequestsWithTarget:o_window];
969 /* Make the window the front and key window before animating */
970 if ([o_window isVisible] && (![o_window isFullscreen]))
971 [o_window makeKeyAndOrderFront: self];
973 [self scaleWindowWithFactor: 1.0 animate: [o_window isVisible] && (![o_window isFullscreen])];
975 [o_embeddedwindow setVideoRatio:[self voutSizeForFactor:1.0]];
977 /* Make sure our window is visible, if we are not in fullscreen */
978 if (![o_window isFullscreen])
979 [o_window makeKeyAndOrderFront: self];
980 [o_window unlockFullscreenAnimation];
987 - (void)setUsed: (BOOL)b_new_used
1001 /* Don't close the window yet, wait a bit to see if a new input is poping up */
1002 /* FIXME: Probably fade the window In and Out */
1003 /* FIXME: fix core */
1004 [o_embeddedwindow performSelector:@selector(orderOut:) withObject:nil afterDelay:3.];
1006 [[[VLCMain sharedInstance] getEmbeddedList] releaseEmbeddedVout: self];
1009 - (void)enterFullscreen
1012 [super enterFullscreen];
1014 /* We are in a VLCEmbeddedWindow */
1015 [o_embeddedwindow performSelectorOnMainThread: @selector(enterFullscreen) withObject: NULL waitUntilDone: YES];
1018 - (void)leaveFullscreen
1021 [super leaveFullscreen];
1023 /* We are in a VLCEmbeddedWindow */
1024 [o_embeddedwindow performSelectorOnMainThread: @selector(leaveFullscreen) withObject: NULL waitUntilDone: YES];
1028 /*****************************************************************************
1029 * VLCVoutWindow implementation
1030 *****************************************************************************/
1031 @implementation VLCVoutWindow
1033 - (id) initWithVout: (vout_thread_t *) vout view: (VLCVoutView *) view
1034 frame: (NSRect *) frame
1040 [self performSelectorOnMainThread: @selector(initMainThread:)
1041 withObject: NULL waitUntilDone: YES];
1043 return b_init_ok ? self : nil;
1046 - (id)initMainThread: (id) sender
1049 rect.size.height = p_vout->i_window_height;
1050 rect.size.width = p_vout->i_window_width;
1051 rect.origin.x = rect.origin.y = 70.;
1053 if( self = [super initWithContentRect:rect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO])
1055 [self setBackgroundColor:[NSColor blackColor]];
1056 [self setHasShadow:YES];
1057 [self setMovableByWindowBackground: YES];
1059 [self makeKeyAndOrderFront: self];
1060 [self setReleasedWhenClosed: YES];
1061 [self setFrameUsingName:@"VLCVoutWindowDetached"];
1062 [self setFrameAutosaveName:@"VLCVoutWindowDetached"];
1064 /* We'll catch mouse events */
1065 [self makeFirstResponder: o_view];
1066 [self setCanBecomeKeyWindow: YES];
1067 [self setAcceptsMouseMovedEvents: YES];
1068 [self setIgnoresMouseEvents: NO];
1070 if( var_CreateGetBool( p_vout, "macosx-background" ) )
1072 int i_device = var_GetInteger( p_vout->p_libvlc, "video-device" );
1074 /* Find out on which screen to open the window */
1075 NSScreen * screen = [NSScreen screenWithDisplayID: (CGDirectDisplayID)i_device];
1076 if( !screen ) screen = [NSScreen mainScreen];
1078 NSRect screen_rect = [screen frame];
1079 screen_rect.origin.x = screen_rect.origin.y = 0;
1081 /* Creates a window with size: screen_rect on o_screen */
1082 [self setFrame: screen_rect display: NO];
1084 [self setLevel: CGWindowLevelForKey(kCGDesktopWindowLevelKey)];
1085 [self setMovableByWindowBackground: NO];
1087 if( var_CreateGetBool( p_vout, "video-on-top" ) )
1089 [self setLevel: NSStatusWindowLevel];
1092 [self setAlphaValue: var_CreateGetFloat( p_vout, "macosx-opaqueness" )];
1094 /* Add the view. It's automatically resized to fit the window */
1095 [self setContentView: o_view];
1102 - (void)enterFullscreen
1104 if( fullscreen ) return;
1110 i_device = var_GetInteger( p_vout->p_libvlc, "video-device" );
1111 b_black = var_CreateGetBool( p_vout, "macosx-black" );
1113 /* Find out on which screen to open the window */
1114 screen = [NSScreen screenWithDisplayID: (CGDirectDisplayID)i_device];
1115 if( !screen ) screen = [self screen];
1118 [screen blackoutOtherScreens];
1120 [self setMovableByWindowBackground: NO];
1122 if( [screen isMainScreen] )
1123 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
1125 initialFrame = [self frame];
1126 [self setFrame:[screen frame] display:YES animate:YES];
1127 [self setLevel:NSNormalWindowLevel];
1129 /* tell the fspanel to move itself to front next time it's triggered */
1130 [[[[VLCMain sharedInstance] getControls] getFSPanel] setVoutWasUpdated: i_device];
1131 [[[[VLCMain sharedInstance] getControls] getFSPanel] setActive: nil];
1136 - (void)leaveFullscreen
1138 if( !fullscreen ) return;
1141 [NSScreen unblackoutScreens];
1143 [[[[VLCMain sharedInstance] getControls] getFSPanel] setNonActive: nil];
1144 SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
1145 [self setFrame:initialFrame display:YES animate:YES];
1146 [self setMovableByWindowBackground: YES];
1147 if( var_GetBool( p_vout, "video-on-top" ) )
1148 [self setLevel: NSStatusWindowLevel];
1151 - (id)getVoutView // FIXME Naming scheme!