📄 vout.m
字号:
/***************************************************************************** * vout.m: MacOS X video output module ***************************************************************************** * Copyright (C) 2001-2005 VideoLAN * $Id: vout.m 11297 2005-06-05 00:48:53Z hartman $ * * 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> * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, 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 "vout.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_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;}/***************************************************************************** * VLCWindow implementation *****************************************************************************/@implementation VLCWindow- (id) initWithVout: (vout_thread_t *) vout view: (NSView *) view frame: (NSRect *) frame{ p_vout = vout; o_view = view; s_frame = frame; [self performSelectorOnMainThread: @selector(initReal:) withObject: NULL waitUntilDone: YES]; if( !b_init_ok ) { return NULL; } return self;}- (id) initReal: (id) sender{ NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; NSArray *o_screens = [NSScreen screens]; NSScreen *o_screen; vlc_bool_t b_menubar_screen = VLC_FALSE; int i_timeout, i_device; vlc_value_t value_drawable; b_init_ok = VLC_FALSE; var_Get( p_vout->p_vlc, "drawable", &value_drawable ); /* We only wait for NSApp to initialise if we're not embedded (as in the * case of the Mozilla plugin). We can tell whether we're embedded or not * by examining the "drawable" value: if it's zero, we're running in the * main Mac intf; if it's non-zero, we're embedded. */ if( value_drawable.i_int == 0 ) { /* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */ for( i_timeout = 20 ; i_timeout-- ; ) { if( NSApp == NULL ) { msleep( INTF_IDLE_SLEEP ); } } if( NSApp == NULL ) { /* No MacOS X intf, unable to communicate with MT */ msg_Err( p_vout, "no MacOS X interface present" ); return NULL; } } if( [o_screens count] <= 0 ) { msg_Err( p_vout, "no OSX screens available" ); return NULL; } /* p_real_vout: the vout we have to use to check for video-on-top and a few other things. If we are the QuickTime output, it's us. It we are the OpenGL provider, it is our parent. */ if( p_vout->i_object_type == VLC_OBJECT_OPENGL ) { p_real_vout = (vout_thread_t *) p_vout->p_parent; } else { p_real_vout = p_vout; } p_fullscreen_state = NULL; i_time_mouse_last_moved = mdate(); var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_vout, "macosx-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_vout, "macosx-opaqueness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); /* 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_vlc, "video-device" ) == 0 ) { i_device = var_GetInteger( p_vout, "macosx-vdev" ); } else { 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 ); 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++; } var_AddCallback( p_real_vout, "video-device", DeviceCallback, NULL ); val2.b_bool = VLC_TRUE; var_Set( p_real_vout, "intf-change", val2 ); } /* Find out on which screen to open the window */ if( i_device <= 0 || i_device > (int)[o_screens count] ) { /* No preference specified. Use the main screen */ o_screen = [NSScreen mainScreen]; if( o_screen == [o_screens objectAtIndex: 0] ) b_menubar_screen = VLC_TRUE; } else { i_device--; o_screen = [o_screens objectAtIndex: i_device]; b_menubar_screen = ( i_device == 0 ); } if( p_vout->b_fullscreen ) { NSRect screen_rect = [o_screen frame]; screen_rect.origin.x = screen_rect.origin.y = 0; /* Creates a window with size: screen_rect on o_screen */ [self initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: YES screen: o_screen]; if( b_menubar_screen ) { BeginFullScreen( &p_fullscreen_state, NULL, 0, 0, NULL, NULL, fullScreenAllowEvents ); } } else { unsigned int i_stylemask = NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask | NSResizableWindowMask; NSRect s_rect; if( !s_frame ) { s_rect.size.width = p_vout->i_window_width; s_rect.size.height = p_vout->i_window_height; } else { s_rect = *s_frame; } [self initWithContentRect: s_rect styleMask: i_stylemask backing: NSBackingStoreBuffered defer: YES screen: o_screen]; [self setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )]; if( var_GetBool( p_real_vout, "video-on-top" ) ) { [self setLevel: NSStatusWindowLevel]; } if( !s_frame ) { [self center]; } } [self updateTitle]; [self makeKeyAndOrderFront: nil]; [self setReleasedWhenClosed: YES]; /* We'll catch mouse events */ [self setAcceptsMouseMovedEvents: YES]; [self makeFirstResponder: self]; /* Add the view. It's automatically resized to fit the window */ [self setContentView: o_view]; [o_pool release]; b_init_ok = VLC_TRUE; return self;}- (void) close{ /* XXX waitUntilDone = NO to avoid a possible deadlock when hitting Command-Q */ [self setAcceptsMouseMovedEvents: NO]; [self setContentView: NULL]; [self performSelectorOnMainThread: @selector(closeReal:) withObject: NULL waitUntilDone: NO];}- (id) closeReal: (id) sender{ [super close]; if( p_fullscreen_state ) { EndFullScreen( p_fullscreen_state, 0 ); } return NULL;}- (void)setOnTop:(BOOL)b_on_top{ if( b_on_top ) { [self setLevel: NSStatusWindowLevel]; } else { [self setLevel: NSNormalWindowLevel]; }}- (void)hideMouse:(BOOL)b_hide{ BOOL b_inside; NSPoint ml; NSView *o_contents = [self contentView]; ml = [self convertScreenToBase:[NSEvent mouseLocation]]; ml = [o_contents convertPoint:ml fromView:nil]; b_inside = [o_contents mouse: ml inRect: [o_contents bounds]]; if( b_hide && b_inside ) { [NSCursor setHiddenUntilMouseMoves: YES]; } else if( !b_hide ) { [NSCursor setHiddenUntilMouseMoves: NO]; }}- (void)manage{ if( p_fullscreen_state ) { if( mdate() - i_time_mouse_last_moved > 3000000 ) { [self hideMouse: YES]; } } else { [self hideMouse: NO]; } /* Disable screensaver */ UpdateSystemActivity( UsrActivity );}- (void)scaleWindowWithFactor: (float)factor{ NSSize newsize; int i_corrected_height, i_corrected_width; NSPoint topleftbase; NSPoint topleftscreen; if ( !p_vout->b_fullscreen ) { topleftbase.x = 0; topleftbase.y = [self frame].size.height; topleftscreen = [self 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -