📄 vout.m
字号:
/***************************************************************************** * vout.m: MacOS X video output module ***************************************************************************** * Copyright (C) 2001-2007 the VideoLAN team * $Id: vout.m 19667 2007-04-04 20:24:46Z fkuehne $ * * 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 K焗ne <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> /* strerror() *//* BeginFullScreen, EndFullScreen */#include <QuickTime/QuickTime.h>#include <vlc_keys.h>#include "intf.h"#include "fspanel.h"#include "vout.h"#import "controls.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; var_Create( p_vout->p_vlc, "video-device", VLC_VAR_INTEGER ); var_Set( p_vout->p_vlc, "video-device", new_val ); val.b_bool = VLC_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: @"VLCWindow"] ) { NSLog( @"We were not given a VLCWindow" ); }*/ 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{ [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 */ i_device = var_GetInteger( p_vout, "macosx-vdev" ); if( var_Type( p_real_vout->p_vlc, "video-device" ) != 0 ) { i_device = var_GetInteger( p_real_vout->p_vlc, "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 = _("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 ); var_AddCallback( p_real_vout, "video-device", DeviceCallback, NULL ); 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 = i; var_Change( p_real_vout, "video-device", VLC_VAR_ADDCHOICE, &val2, &text ); if( i == i_device ) { var_Set( p_real_vout, "video-device", val2 ); } i++; } val2.b_bool = VLC_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)closeVout{ [o_view removeFromSuperview]; o_view = nil; p_vout = NULL; s_frame = nil; o_window = nil; p_real_vout = NULL;}- (void)updateTitle{ NSMutableString * o_title = nil, * o_mrl = nil; input_thread_t * p_input; if( p_vout == NULL ) { return; } p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT, FIND_PARENT ); if( p_input == NULL ) { return; } if( p_input->input.p_item->psz_name != NULL ) o_title = [NSMutableString stringWithUTF8String: p_input->input.p_item->psz_name]; if( p_input->input.p_item->psz_uri != NULL ) o_mrl = [NSMutableString stringWithUTF8String: p_input->input.p_item->psz_uri]; if( o_title == nil ) o_title = o_mrl; if( o_mrl != nil ) { if( p_input->input.p_access && !strcmp( p_input->input.p_access->p_module->psz_shortname, "File" ) ) { NSRange prefix_range = [o_mrl rangeOfString: @"file:"]; if( prefix_range.location != NSNotFound ) [o_mrl deleteCharactersInRange: prefix_range]; [o_window setRepresentedFilename: o_mrl]; } [o_window setTitle: o_title]; } else { [o_window setTitle: [NSString stringWithCString: 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]; }}- (void)scaleWindowWithFactor: (float)factor animate: (BOOL)animate{ NSSize newsize; int i_corrected_height, i_corrected_width; NSPoint topleftbase; NSPoint topleftscreen; if ( !p_vout->b_fullscreen ) { NSRect new_frame; topleftbase.x = 0; topleftbase.y = [o_window frame].size.height; topleftscreen = [o_window convertBaseToScreen: topleftbase]; 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 ); } /* Calculate the window's new size */ new_frame.size.width = [o_window frame].size.width - [self frame].size.width + newsize.width; new_frame.size.height = [o_window frame].size.height - [self frame].size.height + newsize.height; new_frame.origin.x = topleftscreen.x; new_frame.origin.y = topleftscreen.y - new_frame.size.height; [o_window setFrame: new_frame display: animate animate: animate]; p_vout->i_changes |= VOUT_SIZE_CHANGE; }}- (void)toggleFloatOnTop{ vlc_value_t val; if( !p_real_vout ) return; if( var_Get( p_real_vout, "video-on-top", &val )>=0 && val.b_bool) { val.b_bool = VLC_FALSE; } else { val.b_bool = VLC_TRUE; } var_Set( p_real_vout, "video-on-top", val );}- (void)toggleFullscreen{ vlc_value_t val; if( !p_real_vout ) return; var_Get( p_real_vout, "fullscreen", &val ); val.b_bool = !val.b_bool; var_Set( p_real_vout, "fullscreen", val ); if( [self isFullscreen] ) [[[[VLCMain sharedInstance] getControls] getFSPanel] setActive: nil]; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -