📄 wingdi.c
字号:
/***************************************************************************** * wingdi.c : Win32 / WinCE GDI video output plugin for vlc ***************************************************************************** * Copyright (C) 2002 VideoLAN * $Id: wingdi.c 11387 2005-06-10 15:32:08Z hartman $ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h> /* malloc(), free() */#include <string.h>#include <vlc/vlc.h>#include <vlc/vout.h>#include <commctrl.h>#define SHFS_SHOWSIPBUTTON 0x0004#define SHFS_HIDESIPBUTTON 0x0008#ifdef UNDER_CE# define MENU_HEIGHT 26 BOOL SHFullScreen(HWND hwndRequester, DWORD dwState);#else# define MENU_HEIGHT 0# define SHFullScreen(a,b)#endif#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#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 DisplayGAPI( vout_thread_t *, picture_t * );static int GAPILockSurface( vout_thread_t *, picture_t * );static int GAPIUnlockSurface( vout_thread_t *, picture_t * );#elsestatic void DisplayGDI( vout_thread_t *, picture_t * );#endifstatic void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );static void EventThread ( vlc_object_t * );static long FAR PASCAL WndProc ( HWND, UINT, WPARAM, LPARAM );static void InitBuffers ( vout_thread_t * );static void UpdateRects ( vout_thread_t *, vlc_bool_t );static int Control( vout_thread_t *p_vout, int i_query, va_list args );/***************************************************************************** * Private structure *****************************************************************************/struct vout_sys_t{ /* The event thread */ vlc_object_t * p_event; /* Our video output window */ HWND hwnd; HWND hvideownd; HWND hfswnd; int i_depth; HWND hparent; /* Handle of the parent window */ WNDPROC pf_wndproc; /* Window handling callback */ volatile uint16_t i_changes; /* changes made to the video display */ RECT window_placement; /* Window position and size */ int i_window_x; int i_window_y; int i_window_width; int i_window_height; int render_width; int render_height; /* Coordinates of src and dest images (used when blitting to display) */ RECT rect_src; RECT rect_src_clipped; RECT rect_dest; RECT rect_dest_clipped; RECT rect_parent; RECT rect_display; /* Our offscreen bitmap and its framebuffer */ HDC off_dc; HBITMAP off_bitmap; uint8_t * p_pic_buffer; int i_pic_pitch; int i_pic_pixel_pitch; BITMAPINFO bitmapinfo; RGBQUAD red; RGBQUAD green; RGBQUAD blue; /* WINCE stuff */ vlc_bool_t b_video_display; /* Window focus states */ vlc_bool_t b_focus; vlc_bool_t b_parent_focus;#ifdef MODULE_NAME_IS_wingapi HINSTANCE gapi_dll; /* handle of the opened gapi dll */ /* GAPI functions */ int (*GXOpenDisplay)( HWND hWnd, DWORD dwFlags ); int (*GXCloseDisplay)(); void *(*GXBeginDraw)(); int (*GXEndDraw)(); GXDisplayProperties (*GXGetDisplayProperties)(); int (*GXSuspend)(); int (*GXResume)();#endif};#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#ifdef MODULE_NAME_IS_wingapi# define GXSuspend p_vout->p_sys->GXSuspend# define GXResume p_vout->p_sys->GXResume#else# define GXSuspend()# define 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( _("Windows GAPI video output") ); set_capability( "video output", 20 );#else set_shortname( _("Windows GDI") ); set_description( _("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;#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, VLC_OBJECT_GENERIC ); if( !p_vout->p_sys->p_event ) { free( p_vout->p_sys ); return VLC_ENOMEM; } var_Create( p_vout->p_sys->p_event, "p_vout", VLC_VAR_ADDRESS ); val.p_address = (void *)p_vout; var_Set( p_vout->p_sys->p_event, "p_vout", val ); SetRectEmpty( &p_vout->p_sys->rect_display ); SetRectEmpty( &p_vout->p_sys->rect_parent ); if( vlc_thread_create( p_vout->p_sys->p_event, "GDI Event Thread", EventThread, 0, 1 ) ) { msg_Err( p_vout, "cannot spawn EventThread" ); return VLC_ETHREAD; } 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 = DisplayGAPI;#else p_vout->pf_display = DisplayGDI;#endif p_vout->p_sys->i_changes = 0; p_vout->p_sys->b_focus = 0; p_vout->p_sys->b_parent_focus = 0; return VLC_SUCCESS;}/***************************************************************************** * CloseVideo: deactivate the GDI video output *****************************************************************************/static void CloseVideo ( vlc_object_t *p_this ){ vout_thread_t * p_vout = (vout_thread_t *)p_this; p_vout->p_sys->p_event->b_die = VLC_TRUE; PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0 ); vlc_thread_join( p_vout->p_sys->p_event );#ifdef MODULE_NAME_IS_wingapi FreeLibrary( p_vout->p_sys->gapi_dll );#endif var_Destroy( p_vout->p_sys->p_event, "p_vout" ); vlc_object_destroy( p_vout->p_sys->p_event ); free( p_vout->p_sys );}/***************************************************************************** * Init: initialize video thread output method *****************************************************************************/static int Init( vout_thread_t *p_vout ){ picture_t *p_pic; p_vout->p_sys->rect_display.left = 0; p_vout->p_sys->rect_display.top = 0; p_vout->p_sys->rect_display.right = GetSystemMetrics(SM_CXSCREEN); p_vout->p_sys->rect_display.bottom = GetSystemMetrics(SM_CYSCREEN); p_vout->p_sys->b_video_display = VLC_TRUE; p_vout->p_sys->p_event->b_die = VLC_FALSE; I_OUTPUTPICTURES = 0; /* Initialize the output structure */ switch( p_vout->p_sys->i_depth ) { case 8: p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2'); p_vout->output.pf_setpalette = SetPalette; break; case 15: p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5'); p_vout->output.i_rmask = 0x7c00; p_vout->output.i_gmask = 0x03e0; p_vout->output.i_bmask = 0x001f; break; case 16: p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6'); p_vout->output.i_rmask = 0xf800; p_vout->output.i_gmask = 0x07e0; p_vout->output.i_bmask = 0x001f; break; case 24: p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4'); p_vout->output.i_rmask = 0x00ff0000; p_vout->output.i_gmask = 0x0000ff00; p_vout->output.i_bmask = 0x000000ff; break; case 32: p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2'); p_vout->output.i_rmask = 0x00ff0000; p_vout->output.i_gmask = 0x0000ff00; p_vout->output.i_bmask = 0x000000ff; break; default: msg_Err( p_vout, "screen depth %i not supported", p_vout->p_sys->i_depth ); return VLC_EGENERIC; break; } p_pic = &p_vout->p_picture[0];#ifdef MODULE_NAME_IS_wingapi p_vout->output.i_width = 0; p_vout->output.i_height = 0; p_pic->pf_lock = GAPILockSurface; p_pic->pf_unlock = GAPIUnlockSurface; Manage( p_vout ); GAPILockSurface( p_vout, p_pic ); p_vout->i_changes = 0; p_vout->output.i_width = p_vout->p_sys->render_width; p_vout->output.i_height = p_vout->p_sys->render_height;#else p_vout->output.i_width = p_vout->render.i_width; p_vout->output.i_height = p_vout->render.i_height;#endif p_vout->output.i_aspect = p_vout->render.i_aspect; p_pic->p->p_pixels = p_vout->p_sys->p_pic_buffer; p_pic->p->i_lines = p_vout->output.i_height; p_pic->p->i_visible_lines = p_vout->output.i_height; p_pic->p->i_pitch = p_vout->p_sys->i_pic_pitch; p_pic->p->i_pixel_pitch = p_vout->p_sys->i_pic_pixel_pitch; p_pic->p->i_visible_pitch = p_vout->output.i_width * p_pic->p->i_pixel_pitch; p_pic->i_planes = 1; p_pic->i_status = DESTROYED_PICTURE; p_pic->i_type = DIRECT_PICTURE; PP_OUTPUTPICTURE[ I_OUTPUTPICTURES++ ] = p_pic; return VLC_SUCCESS;}/***************************************************************************** * End: terminate video thread output method
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -