📄 vout.m
字号:
/***************************************************************************** * vout.m: MacOS X video output module ***************************************************************************** * Copyright (C) 2001-2008 the VideoLAN team * $Id$ * * Authors: Colin Delacroix <colin@zoy.org> * Florian G. Pflug <fgp@phlo.org> * Jon Lech Johansen <jon-vl@nanocrew.net> * Derk-Jan Hartman <hartman at videolan dot org> * Eric Petit <titer@m0k.org> * Benjamin Pracht <bigben at videolan dot org> * Felix Paul Kühne <fkuehne at videolan dot org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <errno.h> /* ENOMEM */#include <stdlib.h> /* free() */#include <string.h>/* BeginFullScreen, EndFullScreen */#include <QuickTime/QuickTime.h>#include <vlc_keys.h>#include "intf.h"#include "fspanel.h"#include "vout.h"#import "controls.h"#import "embeddedwindow.h"/***************************************************************************** * DeviceCallback: Callback triggered when the video-device variable is changed *****************************************************************************/int DeviceCallback( vlc_object_t *p_this, const char *psz_variable, vlc_value_t old_val, vlc_value_t new_val, void *param ){ vlc_value_t val; vout_thread_t *p_vout = (vout_thread_t *)p_this; msg_Dbg( p_vout, "set %d", new_val.i_int ); var_Create( p_vout->p_libvlc, "video-device", VLC_VAR_INTEGER ); var_Set( p_vout->p_libvlc, "video-device", new_val ); val.b_bool = true; var_Set( p_vout, "intf-change", val ); return VLC_SUCCESS;}/***************************************************************************** * VLCEmbeddedList implementation *****************************************************************************/@implementation VLCEmbeddedList- (id)init{ [super init]; o_embedded_array = [NSMutableArray array]; return self;}- (id)getEmbeddedVout{ unsigned int i; for( i = 0; i < [o_embedded_array count]; i++ ) { id o_vout_view = [o_embedded_array objectAtIndex: i]; if( ![o_vout_view isUsed] ) { [o_vout_view setUsed: YES]; return o_vout_view; } } return nil;}- (void)releaseEmbeddedVout: (id)o_vout_view{ if( [o_embedded_array containsObject: o_vout_view] ) { [o_vout_view setUsed: NO]; } else { msg_Warn( VLCIntf, "cannot find Video Output"); }}- (void)addEmbeddedVout: (id)o_vout_view{ if( ![o_embedded_array containsObject: o_vout_view] ) { [o_embedded_array addObject: o_vout_view]; }}- (BOOL)windowContainsEmbedded: (id)o_window{/* if( ![[o_window className] isEqualToString: @"VLCVoutWindow"] ) { NSLog( @"We were not given a VLCVoutWindow" ); }*/ return ([self getViewForWindow: o_window] == nil ? NO : YES );}- (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_current_embedded getWindow] == o_window ) { return o_current_embedded; } } return nil;}@end/***************************************************************************** * VLCVoutView implementation *****************************************************************************/@implementation VLCVoutView- (id)initWithFrame: (NSRect)frameRect{ self = [super initWithFrame: frameRect]; p_vout = NULL; o_view = nil; s_frame = &frameRect; p_real_vout = NULL; o_window = nil; return self;}- (BOOL)setVout: (vout_thread_t *) vout subView: (NSView *) view frame: (NSRect *) frame{ int i_device; NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; NSArray *o_screens = [NSScreen screens]; p_vout = vout; o_view = view; s_frame = frame; if( [o_screens count] <= 0 ) { msg_Err( p_vout, "no OSX screens available" ); return NO; } p_real_vout = [VLCVoutView getRealVout: p_vout]; /* Get the pref value when this is the first time, otherwise retrieve the device from the top level video-device var */ if( var_Type( p_real_vout->p_libvlc, "video-device" ) == 0 ) { i_device = var_GetInteger( p_vout, "macosx-vdev" ); } else { i_device = var_GetInteger( p_real_vout->p_libvlc, "video-device" ); } /* Setup the menuitem for the multiple displays. */ if( var_Type( p_real_vout, "video-device" ) == 0 ) { int i = 1; vlc_value_t val2, text; NSScreen * o_screen; var_Create( p_real_vout, "video-device", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Fullscreen Video Device"); var_Change( p_real_vout, "video-device", VLC_VAR_SETTEXT, &text, NULL ); NSEnumerator * o_enumerator = [o_screens objectEnumerator]; val2.i_int = 0; text.psz_string = _("Default"); var_Change( p_real_vout, "video-device", VLC_VAR_ADDCHOICE, &val2, &text ); var_Set( p_real_vout, "video-device", val2 ); while( (o_screen = [o_enumerator nextObject]) != NULL ) { char psz_temp[255]; NSRect s_rect = [o_screen frame]; snprintf( psz_temp, sizeof(psz_temp)/sizeof(psz_temp[0])-1, "%s %d (%dx%d)", _("Screen"), i, (int)s_rect.size.width, (int)s_rect.size.height ); text.psz_string = psz_temp; val2.i_int = (int)[o_screen displayID]; var_Change( p_real_vout, "video-device", VLC_VAR_ADDCHOICE, &val2, &text ); if( (int)[o_screen displayID] == i_device ) { var_Set( p_real_vout, "video-device", val2 ); } i++; } var_AddCallback( p_real_vout, "video-device", DeviceCallback, NULL ); val2.b_bool = true; var_Set( p_real_vout, "intf-change", val2 ); } /* Add the view. It's automatically resized to fit the window */ [self addSubview: o_view]; [self setAutoresizesSubviews: YES]; [o_pool release]; return YES;}- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize{ [super resizeSubviewsWithOldSize: oldBoundsSize]; [o_view setFrameSize: [self frame].size];}- (void)drawRect:(NSRect)rect{ /* When there is no subview we draw a black background */ [self lockFocus]; [[NSColor blackColor] set]; NSRectFill(rect); [self unlockFocus];}- (void)closeVout{ [[[[VLCMain sharedInstance] getControls] getFSPanel] fadeOut]; /* Make sure we don't see a white flash */ [[self window] disableScreenUpdatesUntilFlush]; [o_view removeFromSuperview]; o_view = nil; p_vout = NULL; s_frame = nil; o_window = nil; p_real_vout = NULL;}- (void)updateTitle{ NSString * o_title = nil; NSMutableString * o_mrl = nil; input_thread_t * p_input; char * psz_title; if( !p_vout ) return; p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT ); if( !p_input ) return; input_item_t * p_item = input_GetItem( p_input ); psz_title = input_item_GetNowPlaying ( p_item ); if( !psz_title ) psz_title = input_item_GetName( p_item ); if( psz_title ) o_title = [NSString stringWithUTF8String: psz_title]; char *psz_uri = input_item_GetURI( p_item ); if( psz_uri ) o_mrl = [NSMutableString stringWithUTF8String: psz_uri]; free( psz_title ); free( psz_uri ); if( !o_title ) o_title = o_mrl; if( o_mrl != nil ) { /* FIXME once psz_access is exported, we could check if we are * reading from a file in a smarter way. */ NSRange prefix_range = [o_mrl rangeOfString: @"file:"]; if( prefix_range.location != NSNotFound ) [o_mrl deleteCharactersInRange: prefix_range]; if( [o_mrl characterAtIndex:0] == '/' ) { /* it's a local file */ [o_window setRepresentedFilename: o_mrl]; } else { /* it's from the network or somewhere else, * we clear the previous path */ [o_window setRepresentedFilename: @""]; } [o_window setTitle: o_title]; } else { [o_window setTitle: [NSString stringWithUTF8String: VOUT_TITLE]]; } vlc_object_release( p_input );}- (void)setOnTop:(BOOL)b_on_top{ if( b_on_top ) { [o_window setLevel: NSStatusWindowLevel]; } else { [o_window setLevel: NSNormalWindowLevel]; }}- (NSSize)voutSizeForFactor: (float)factor{ int i_corrected_height, i_corrected_width; NSSize newsize; if( p_vout->render.i_height * p_vout->render.i_aspect > p_vout->render.i_width * VOUT_ASPECT_FACTOR ) { i_corrected_width = p_vout->render.i_height * p_vout->render.i_aspect / VOUT_ASPECT_FACTOR; newsize.width = (int) ( i_corrected_width * factor ); newsize.height = (int) ( p_vout->render.i_height * factor ); } else { i_corrected_height = p_vout->render.i_width * VOUT_ASPECT_FACTOR / p_vout->render.i_aspect; newsize.width = (int) ( p_vout->render.i_width * factor ); newsize.height = (int) ( i_corrected_height * factor ); } return newsize;}- (void)scaleWindowWithFactor: (float)factor animate: (BOOL)animate{ if ( !p_vout->b_fullscreen ) { NSSize newsize; NSPoint topleftbase; NSPoint topleftscreen; NSView *mainView; NSRect new_frame; topleftbase.x = 0; topleftbase.y = [o_window frame].size.height; topleftscreen = [o_window convertBaseToScreen: topleftbase]; newsize = [self voutSizeForFactor:factor]; /* In fullscreen mode we need to use a view that is different from
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -