📄 wingdi.c
字号:
/***************************************************************************** * wingdi.c : Win32 / WinCE GDI video output plugin for vlc ***************************************************************************** * Copyright (C) 2002 the VideoLAN team * $Id: 310d3ea4657e282eb40700355a5ed199b6755f3a $ * * Authors: Gildas Bazin <gbazin@videolan.org> * Samuel Hocevar <sam@zoy.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 *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_interface.h>#include <vlc_playlist.h>#include <vlc_vout.h>#include <commctrl.h>#include "vout.h"#ifdef MODULE_NAME_IS_wingapi typedef struct GXDisplayProperties { DWORD cxWidth; DWORD cyHeight; long cbxPitch; long cbyPitch; long cBPP; DWORD ffFormat; } GXDisplayProperties; typedef struct GXScreenRect { DWORD dwTop; DWORD dwLeft; DWORD dwWidth; DWORD dwHeight; } GXScreenRect;# define GX_FULLSCREEN 0x01# define GX_NORMALKEYS 0x02# define GX_LANDSCAPEKEYS 0x03# ifndef kfLandscape# define kfLandscape 0x8# define kfPalette 0x10# define kfDirect 0x20# define kfDirect555 0x40# define kfDirect565 0x80# define kfDirect888 0x100# define kfDirect444 0x200# define kfDirectInverted 0x400# endif#endif /* MODULE_NAME_IS_wingapi */#define MAX_DIRECTBUFFERS 10#ifdef UNDER_CE#ifndef WS_OVERLAPPEDWINDOW# define WS_OVERLAPPEDWINDOW 0xcf0000#endif#ifndef WS_EX_NOPARENTNOTIFY# define WS_EX_NOPARENTNOTIFY 4#endif#ifndef WS_EX_APPWINDOW#define WS_EX_APPWINDOW 0x40000#endif#define SetWindowLongPtr SetWindowLong#define GetWindowLongPtr GetWindowLong#define GWLP_USERDATA GWL_USERDATA#define AdjustWindowRect(a,b,c)#endif //UNDER_CE#ifndef WS_NONAVDONEBUTTON#define WS_NONAVDONEBUTTON 0#endif/***************************************************************************** * Local prototypes *****************************************************************************/static int OpenVideo ( vlc_object_t * );static void CloseVideo ( vlc_object_t * );static int Init ( vout_thread_t * );static void End ( vout_thread_t * );static int Manage ( vout_thread_t * );static void Render ( vout_thread_t *, picture_t * );#ifdef MODULE_NAME_IS_wingapistatic void FirstDisplayGAPI( vout_thread_t *, picture_t * );static void DisplayGAPI( vout_thread_t *, picture_t * );static int GAPILockSurface( vout_thread_t *, picture_t * );static int GAPIUnlockSurface( vout_thread_t *, picture_t * );#elsestatic void FirstDisplayGDI( vout_thread_t *, picture_t * );static void DisplayGDI( vout_thread_t *, picture_t * );#endifstatic void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );static void InitBuffers ( vout_thread_t * );#ifdef MODULE_NAME_IS_wingapi# define GXOpenDisplay p_vout->p_sys->GXOpenDisplay# define GXCloseDisplay p_vout->p_sys->GXCloseDisplay# define GXBeginDraw p_vout->p_sys->GXBeginDraw# define GXEndDraw p_vout->p_sys->GXEndDraw# define GXGetDisplayProperties p_vout->p_sys->GXGetDisplayProperties# define GXSuspend p_vout->p_sys->GXSuspend# define GXResume p_vout->p_sys->GXResume#endif#define DX_POSITION_CHANGE 0x1000/***************************************************************************** * Module descriptor *****************************************************************************/vlc_module_begin(); set_category( CAT_VIDEO ); set_subcategory( SUBCAT_VIDEO_VOUT );#ifdef MODULE_NAME_IS_wingapi set_shortname( "Windows GAPI" ); set_description( N_("Windows GAPI video output") ); set_capability( "video output", 20 );#else set_shortname( "Windows GDI" ); set_description( N_("Windows GDI video output") ); set_capability( "video output", 10 );#endif set_callbacks( OpenVideo, CloseVideo );vlc_module_end();/***************************************************************************** * OpenVideo: activate GDI video thread output method *****************************************************************************/static int OpenVideo ( vlc_object_t *p_this ){ vout_thread_t * p_vout = (vout_thread_t *)p_this; vlc_value_t val; p_vout->p_sys = (vout_sys_t *)malloc( sizeof(vout_sys_t) ); if( !p_vout->p_sys ) return VLC_ENOMEM; memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );#ifdef MODULE_NAME_IS_wingapi /* Load GAPI */ p_vout->p_sys->gapi_dll = LoadLibrary( _T("GX.DLL") ); if( p_vout->p_sys->gapi_dll == NULL ) { msg_Warn( p_vout, "failed loading gx.dll" ); free( p_vout->p_sys ); return VLC_EGENERIC; } GXOpenDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXOpenDisplay@@YAHPAUHWND__@@K@Z") ); GXCloseDisplay = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXCloseDisplay@@YAHXZ") ); GXBeginDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXBeginDraw@@YAPAXXZ") ); GXEndDraw = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXEndDraw@@YAHXZ") ); GXGetDisplayProperties = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ") ); GXSuspend = (void *)GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXSuspend@@YAHXZ") ); GXResume = GetProcAddress( p_vout->p_sys->gapi_dll, _T("?GXResume@@YAHXZ") ); if( !GXOpenDisplay || !GXCloseDisplay || !GXBeginDraw || !GXEndDraw || !GXGetDisplayProperties || !GXSuspend || !GXResume ) { msg_Err( p_vout, "failed GetProcAddress on gapi.dll" ); free( p_vout->p_sys ); return VLC_EGENERIC; } msg_Dbg( p_vout, "GAPI DLL loaded" ); p_vout->p_sys->render_width = p_vout->render.i_width; p_vout->p_sys->render_height = p_vout->render.i_height;#endif p_vout->p_sys->p_event = (vlc_object_t *) vlc_object_create( p_vout, sizeof( vlc_object_t ) ); if( !p_vout->p_sys->p_event ) { free( p_vout->p_sys ); return VLC_ENOMEM; } p_vout->pf_init = Init; p_vout->pf_end = End; p_vout->pf_manage = Manage; p_vout->pf_render = Render;#ifdef MODULE_NAME_IS_wingapi p_vout->pf_display = FirstDisplayGAPI; p_vout->p_sys->b_focus = 0; p_vout->p_sys->b_parent_focus = 0;#else p_vout->pf_display = FirstDisplayGDI;#endif p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL; p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL; p_vout->p_sys->i_changes = 0; vlc_mutex_init( &p_vout->p_sys->lock ); SetRectEmpty( &p_vout->p_sys->rect_display ); SetRectEmpty( &p_vout->p_sys->rect_parent ); var_Create( p_vout, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_vout, "disable-screensaver", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); p_vout->p_sys->b_cursor_hidden = 0; p_vout->p_sys->i_lastmoved = mdate(); p_vout->p_sys->i_mouse_hide_timeout = var_GetInteger(p_vout, "mouse-hide-timeout") * 1000; /* Set main window's size */ p_vout->p_sys->i_window_width = p_vout->i_window_width; p_vout->p_sys->i_window_height = p_vout->i_window_height; /* Create the EventThread, this thread is created by us to isolate * the Win32 PeekMessage function calls. We want to do this because * Windows can stay blocked inside this call for a long time, and when * this happens it thus blocks vlc's video_output thread. * Vout EventThread will take care of the creation of the video * window (because PeekMessage has to be called from the same thread which * created the window). */ msg_Dbg( p_vout, "creating Vout EventThread" ); p_vout->p_sys->p_event = vlc_object_create( p_vout, sizeof(event_thread_t) ); p_vout->p_sys->p_event->p_vout = p_vout; if( vlc_thread_create( p_vout->p_sys->p_event, "VLC Vout Events Thread", EventThread, 0, 1 ) ) { msg_Err( p_vout, "cannot create Vout EventThread" ); vlc_object_release( p_vout->p_sys->p_event ); p_vout->p_sys->p_event = NULL; goto error; } if( p_vout->p_sys->p_event->b_error ) { msg_Err( p_vout, "Vout EventThread failed" ); goto error; } vlc_object_attach( p_vout->p_sys->p_event, p_vout ); msg_Dbg( p_vout, "Vout EventThread running" );#ifndef UNDER_CE /* Variable to indicate if the window should be on top of others */ /* Trigger a callback right now */ var_Get( p_vout, "video-on-top", &val ); var_Set( p_vout, "video-on-top", val ); /* disable screensaver by temporarily changing system settings */ p_vout->p_sys->i_spi_lowpowertimeout = 0; p_vout->p_sys->i_spi_powerofftimeout = 0; p_vout->p_sys->i_spi_screensavetimeout = 0; var_Get( p_vout, "disable-screensaver", &val); if( val.b_bool ) { msg_Dbg(p_vout, "disabling screen saver"); SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT, 0, &(p_vout->p_sys->i_spi_lowpowertimeout), 0); if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) { SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0); } SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0, &(p_vout->p_sys->i_spi_powerofftimeout), 0); if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) { SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 0, NULL, 0); } SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &(p_vout->p_sys->i_spi_screensavetimeout), 0); if( 0 != p_vout->p_sys->i_spi_screensavetimeout ) { SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0); } }#endif return VLC_SUCCESS;error: CloseVideo( VLC_OBJECT(p_vout) ); return VLC_EGENERIC;}/*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -