Commit e54cc504 authored by Damien Fouilleul's avatar Damien Fouilleul

vout: merged all Microsoft Windows specific vouts under msw directory in order...

vout: merged all Microsoft Windows specific vouts under msw directory in order to leverage common event handling
parent dde6aaf8
...@@ -5916,7 +5916,7 @@ AC_CONFIG_FILES([ ...@@ -5916,7 +5916,7 @@ AC_CONFIG_FILES([
modules/video_chroma/Makefile modules/video_chroma/Makefile
modules/video_filter/Makefile modules/video_filter/Makefile
modules/video_output/Makefile modules/video_output/Makefile
modules/video_output/directx/Makefile modules/video_output/msw/Makefile
modules/video_output/qte/Makefile modules/video_output/qte/Makefile
modules/video_output/x11/Makefile modules/video_output/x11/Makefile
modules/visualization/Makefile modules/visualization/Makefile
......
...@@ -5,8 +5,6 @@ SOURCES_ggi = ggi.c ...@@ -5,8 +5,6 @@ SOURCES_ggi = ggi.c
SOURCES_glide = glide.c SOURCES_glide = glide.c
SOURCES_vout_sdl = sdl.c SOURCES_vout_sdl = sdl.c
SOURCES_svgalib = svgalib.c SOURCES_svgalib = svgalib.c
SOURCES_wingdi = wingdi.c
SOURCES_wingapi = wingdi.c
SOURCES_mga = mga.c SOURCES_mga = mga.c
SOURCES_hd1000v = hd1000v.cpp SOURCES_hd1000v = hd1000v.cpp
SOURCES_snapshot = snapshot.c SOURCES_snapshot = snapshot.c
......
...@@ -15,3 +15,15 @@ SOURCES_glwin32 = \ ...@@ -15,3 +15,15 @@ SOURCES_glwin32 = \
vout.h \ vout.h \
events.c \ events.c \
$(NULL) $(NULL)
SOURCES_wingdi = \
wingdi.c \
vout.h \
events.c \
$(NULL)
SOURCES_wingapi = \
windi.c \
vout.h \
events.c \
$(NULL)
...@@ -138,7 +138,7 @@ typedef struct ...@@ -138,7 +138,7 @@ typedef struct
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1) #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
/***************************************************************************** /*****************************************************************************
* OpenVideo: allocate DirectX video thread output method * OpenVideo: allocate Vout video thread output method
***************************************************************************** *****************************************************************************
* This function allocates and initialize the Direct3D vout method. * This function allocates and initialize the Direct3D vout method.
*****************************************************************************/ *****************************************************************************/
...@@ -172,15 +172,12 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -172,15 +172,12 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL; 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->hparent = p_vout->p_sys->hfswnd = NULL;
p_vout->p_sys->i_changes = 0; p_vout->p_sys->i_changes = 0;
p_vout->p_sys->b_wallpaper = 0;
vlc_mutex_init( p_vout, &p_vout->p_sys->lock ); vlc_mutex_init( p_vout, &p_vout->p_sys->lock );
SetRectEmpty( &p_vout->p_sys->rect_display ); SetRectEmpty( &p_vout->p_sys->rect_display );
SetRectEmpty( &p_vout->p_sys->rect_parent ); SetRectEmpty( &p_vout->p_sys->rect_parent );
var_Create( p_vout, "directx-hw-yuv", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_vout, "directx-hw-yuv", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_vout, "directx-device", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_vout, "directx-device", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
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->b_cursor_hidden = 0;
p_vout->p_sys->i_lastmoved = mdate(); p_vout->p_sys->i_lastmoved = mdate();
...@@ -192,21 +189,21 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -192,21 +189,21 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->i_window_width = p_vout->i_window_width; p_vout->p_sys->i_window_width = p_vout->i_window_width;
p_vout->p_sys->i_window_height = p_vout->i_window_height; p_vout->p_sys->i_window_height = p_vout->i_window_height;
/* Create the DirectXEventThread, this thread is created by us to isolate /* Create the Vout EventThread, this thread is created by us to isolate
* the Win32 PeekMessage function calls. We want to do this because * the Win32 PeekMessage function calls. We want to do this because
* Windows can stay blocked inside this call for a long time, and when * Windows can stay blocked inside this call for a long time, and when
* this happens it thus blocks vlc's video_output thread. * this happens it thus blocks vlc's video_output thread.
* DirectXEventThread will take care of the creation of the video * Vout EventThread will take care of the creation of the video
* window (because PeekMessage has to be called from the same thread which * window (because PeekMessage has to be called from the same thread which
* created the window). */ * created the window). */
msg_Dbg( p_vout, "creating DirectXEventThread" ); msg_Dbg( p_vout, "creating Vout EventThread" );
p_vout->p_sys->p_event = p_vout->p_sys->p_event =
vlc_object_create( p_vout, sizeof(event_thread_t) ); vlc_object_create( p_vout, sizeof(event_thread_t) );
p_vout->p_sys->p_event->p_vout = p_vout; p_vout->p_sys->p_event->p_vout = p_vout;
if( vlc_thread_create( p_vout->p_sys->p_event, "DirectX Events Thread", if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",
E_(DirectXEventThread), 0, 1 ) ) E_(EventThread), 0, 1 ) )
{ {
msg_Err( p_vout, "cannot create DirectXEventThread" ); msg_Err( p_vout, "cannot create Vout EventThread" );
vlc_object_destroy( p_vout->p_sys->p_event ); vlc_object_destroy( p_vout->p_sys->p_event );
p_vout->p_sys->p_event = NULL; p_vout->p_sys->p_event = NULL;
goto error; goto error;
...@@ -214,13 +211,13 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -214,13 +211,13 @@ static int OpenVideo( vlc_object_t *p_this )
if( p_vout->p_sys->p_event->b_error ) if( p_vout->p_sys->p_event->b_error )
{ {
msg_Err( p_vout, "DirectXEventThread failed" ); msg_Err( p_vout, "Vout EventThread failed" );
goto error; goto error;
} }
vlc_object_attach( p_vout->p_sys->p_event, p_vout ); vlc_object_attach( p_vout->p_sys->p_event, p_vout );
msg_Dbg( p_vout, "DirectXEventThread running" ); msg_Dbg( p_vout, "Vout EventThread running" );
/* Variable to indicate if the window should be on top of others */ /* Variable to indicate if the window should be on top of others */
/* Trigger a callback right now */ /* Trigger a callback right now */
...@@ -272,10 +269,10 @@ static void CloseVideo( vlc_object_t *p_this ) ...@@ -272,10 +269,10 @@ static void CloseVideo( vlc_object_t *p_this )
{ {
vlc_object_detach( p_vout->p_sys->p_event ); vlc_object_detach( p_vout->p_sys->p_event );
/* Kill DirectXEventThread */ /* Kill Vout EventThread */
p_vout->p_sys->p_event->b_die = VLC_TRUE; p_vout->p_sys->p_event->b_die = VLC_TRUE;
/* we need to be sure DirectXEventThread won't stay stuck in /* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */ * GetMessage, so we send a fake message */
if( p_vout->p_sys->hwnd ) if( p_vout->p_sys->hwnd )
{ {
...@@ -334,7 +331,7 @@ static int Init( vout_thread_t *p_vout ) ...@@ -334,7 +331,7 @@ static int Init( vout_thread_t *p_vout )
p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect; p_vout->output.i_aspect = p_vout->render.i_aspect;
p_vout->fmt_out = p_vout->fmt_in; p_vout->fmt_out = p_vout->fmt_in;
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
/* create picture pool */ /* create picture pool */
i_ret = Direct3DVoutCreatePictures(p_vout, 1); i_ret = Direct3DVoutCreatePictures(p_vout, 1);
...@@ -451,7 +448,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -451,7 +448,7 @@ static int Manage( vout_thread_t *p_vout )
p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num; p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den; p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
p_vout->output.i_aspect = p_vout->fmt_in.i_aspect; p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
} }
/* We used to call the Win32 PeekMessage function here to read the window /* We used to call the Win32 PeekMessage function here to read the window
...@@ -708,7 +705,8 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout ) ...@@ -708,7 +705,8 @@ static int Direct3DVoutOpen( vout_thread_t *p_vout )
// Create the D3DDevice // Create the D3DDevice
hr = IDirect3D9_CreateDevice(p_d3dobj, D3DADAPTER_DEFAULT, hr = IDirect3D9_CreateDevice(p_d3dobj, D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, p_vout->p_sys->hvideownd, D3DDEVTYPE_HAL, p_vout->p_sys->hvideownd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DCREATE_SOFTWARE_VERTEXPROCESSING|
D3DCREATE_MULTITHREADED,
&d3dpp, &p_d3ddev ); &d3dpp, &p_d3ddev );
if( FAILED(hr) ) if( FAILED(hr) )
{ {
......
...@@ -264,7 +264,7 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -264,7 +264,7 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->i_window_width = p_vout->i_window_width; p_vout->p_sys->i_window_width = p_vout->i_window_width;
p_vout->p_sys->i_window_height = p_vout->i_window_height; p_vout->p_sys->i_window_height = p_vout->i_window_height;
/* Create the DirectXEventThread, this thread is created by us to isolate /* Create the Vout EventThread, this thread is created by us to isolate
* the Win32 PeekMessage function calls. We want to do this because * the Win32 PeekMessage function calls. We want to do this because
* Windows can stay blocked inside this call for a long time, and when * Windows can stay blocked inside this call for a long time, and when
* this happens it thus blocks vlc's video_output thread. * this happens it thus blocks vlc's video_output thread.
...@@ -275,10 +275,10 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -275,10 +275,10 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->p_event = p_vout->p_sys->p_event =
vlc_object_create( p_vout, sizeof(event_thread_t) ); vlc_object_create( p_vout, sizeof(event_thread_t) );
p_vout->p_sys->p_event->p_vout = p_vout; p_vout->p_sys->p_event->p_vout = p_vout;
if( vlc_thread_create( p_vout->p_sys->p_event, "DirectX Events Thread", if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",
E_(DirectXEventThread), 0, 1 ) ) E_(EventThread), 0, 1 ) )
{ {
msg_Err( p_vout, "cannot create DirectXEventThread" ); msg_Err( p_vout, "cannot create Vout EventThread" );
vlc_object_destroy( p_vout->p_sys->p_event ); vlc_object_destroy( p_vout->p_sys->p_event );
p_vout->p_sys->p_event = NULL; p_vout->p_sys->p_event = NULL;
goto error; goto error;
...@@ -286,25 +286,25 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -286,25 +286,25 @@ static int OpenVideo( vlc_object_t *p_this )
if( p_vout->p_sys->p_event->b_error ) if( p_vout->p_sys->p_event->b_error )
{ {
msg_Err( p_vout, "DirectXEventThread failed" ); msg_Err( p_vout, "Vout EventThread failed" );
goto error; goto error;
} }
vlc_object_attach( p_vout->p_sys->p_event, p_vout ); vlc_object_attach( p_vout->p_sys->p_event, p_vout );
msg_Dbg( p_vout, "DirectXEventThread running" ); msg_Dbg( p_vout, "Vout EventThread running" );
/* Initialise DirectDraw */ /* Initialise DirectDraw */
if( DirectXInitDDraw( p_vout ) ) if( DirectXInitDDraw( p_vout ) )
{ {
msg_Err( p_vout, "cannot initialize DirectDraw" ); msg_Err( p_vout, "cannot initialize DirectX DirectDraw" );
goto error; goto error;
} }
/* Create the directx display */ /* Create the directx display */
if( DirectXCreateDisplay( p_vout ) ) if( DirectXCreateDisplay( p_vout ) )
{ {
msg_Err( p_vout, "cannot initialize DirectDraw" ); msg_Err( p_vout, "cannot initialize DirectX DirectDraw" );
goto error; goto error;
} }
...@@ -399,7 +399,7 @@ static int Init( vout_thread_t *p_vout ) ...@@ -399,7 +399,7 @@ static int Init( vout_thread_t *p_vout )
p_vout->output.i_height = p_vout->render.i_height; p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect; p_vout->output.i_aspect = p_vout->render.i_aspect;
p_vout->fmt_out = p_vout->fmt_in; p_vout->fmt_out = p_vout->fmt_in;
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
#define MAX_DIRECTBUFFERS 1 #define MAX_DIRECTBUFFERS 1
/* Right now we use only 1 directbuffer because we don't want the /* Right now we use only 1 directbuffer because we don't want the
...@@ -492,10 +492,10 @@ static void CloseVideo( vlc_object_t *p_this ) ...@@ -492,10 +492,10 @@ static void CloseVideo( vlc_object_t *p_this )
{ {
vlc_object_detach( p_vout->p_sys->p_event ); vlc_object_detach( p_vout->p_sys->p_event );
/* Kill DirectXEventThread */ /* Kill Vout EventThread */
p_vout->p_sys->p_event->b_die = VLC_TRUE; p_vout->p_sys->p_event->b_die = VLC_TRUE;
/* we need to be sure DirectXEventThread won't stay stuck in /* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */ * GetMessage, so we send a fake message */
if( p_vout->p_sys->hwnd ) if( p_vout->p_sys->hwnd )
{ {
...@@ -608,7 +608,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -608,7 +608,7 @@ static int Manage( vout_thread_t *p_vout )
p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num; p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den; p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
p_vout->output.i_aspect = p_vout->fmt_in.i_aspect; p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
} }
/* We used to call the Win32 PeekMessage function here to read the window /* We used to call the Win32 PeekMessage function here to read the window
...@@ -620,7 +620,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -620,7 +620,7 @@ static int Manage( vout_thread_t *p_vout )
{ {
SwitchWallpaperMode( p_vout, !p_vout->p_sys->b_wallpaper ); SwitchWallpaperMode( p_vout, !p_vout->p_sys->b_wallpaper );
p_vout->p_sys->i_changes &= ~DX_WALLPAPER_CHANGE; p_vout->p_sys->i_changes &= ~DX_WALLPAPER_CHANGE;
E_(DirectXUpdateOverlay)( p_vout ); DirectDrawUpdateOverlay( p_vout );
} }
/* /*
...@@ -722,7 +722,7 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -722,7 +722,7 @@ static void Display( vout_thread_t *p_vout, picture_t *p_pic )
{ {
if( IDirectDrawSurface2_Restore( p_vout->p_sys->p_display ) == DD_OK && if( IDirectDrawSurface2_Restore( p_vout->p_sys->p_display ) == DD_OK &&
p_vout->p_sys->b_using_overlay ) p_vout->p_sys->b_using_overlay )
E_(DirectXUpdateOverlay)( p_vout ); DirectDrawUpdateOverlay( p_vout );
} }
if( !p_vout->p_sys->b_using_overlay ) if( !p_vout->p_sys->b_using_overlay )
...@@ -1056,7 +1056,7 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout ) ...@@ -1056,7 +1056,7 @@ static int DirectXCreateDisplay( vout_thread_t *p_vout )
p_vout->p_sys->i_rgb_colorkey = p_vout->p_sys->i_rgb_colorkey =
DirectXFindColorkey( p_vout, &p_vout->p_sys->i_colorkey ); DirectXFindColorkey( p_vout, &p_vout->p_sys->i_colorkey );
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1224,7 +1224,7 @@ static int DirectXCreateSurface( vout_thread_t *p_vout, ...@@ -1224,7 +1224,7 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
/* Check the overlay is useable as some graphics cards allow creating /* Check the overlay is useable as some graphics cards allow creating
* several overlays but only one can be used at one time. */ * several overlays but only one can be used at one time. */
p_vout->p_sys->p_current_surface = *pp_surface_final; p_vout->p_sys->p_current_surface = *pp_surface_final;
if( E_(DirectXUpdateOverlay)( p_vout ) != VLC_SUCCESS ) if( DirectDrawUpdateOverlay( p_vout ) != VLC_SUCCESS )
{ {
IDirectDrawSurface2_Release( *pp_surface_final ); IDirectDrawSurface2_Release( *pp_surface_final );
*pp_surface_final = NULL; *pp_surface_final = NULL;
...@@ -1237,13 +1237,13 @@ static int DirectXCreateSurface( vout_thread_t *p_vout, ...@@ -1237,13 +1237,13 @@ static int DirectXCreateSurface( vout_thread_t *p_vout,
} }
/***************************************************************************** /*****************************************************************************
* DirectXUpdateOverlay: Move or resize overlay surface on video display. * DirectDrawUpdateOverlay: Move or resize overlay surface on video display.
***************************************************************************** *****************************************************************************
* This function is used to move or resize an overlay surface on the screen. * This function is used to move or resize an overlay surface on the screen.
* Ususally the overlay is moved by the user and thus, by a move or resize * Ususally the overlay is moved by the user and thus, by a move or resize
* event (in Manage). * event (in Manage).
*****************************************************************************/ *****************************************************************************/
int E_(DirectXUpdateOverlay)( vout_thread_t *p_vout ) int DirectDrawUpdateOverlay( vout_thread_t *p_vout )
{ {
DDOVERLAYFX ddofx; DDOVERLAYFX ddofx;
DWORD dwFlags; DWORD dwFlags;
...@@ -1299,7 +1299,7 @@ int E_(DirectXUpdateOverlay)( vout_thread_t *p_vout ) ...@@ -1299,7 +1299,7 @@ int E_(DirectXUpdateOverlay)( vout_thread_t *p_vout )
if(dxresult != DD_OK) if(dxresult != DD_OK)
{ {
msg_Warn( p_vout, "DirectXUpdateOverlay cannot move/resize overlay" ); msg_Warn( p_vout, "DirectDrawUpdateOverlay cannot move/resize overlay" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -1465,7 +1465,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1465,7 +1465,7 @@ static int NewPictureVec( vout_thread_t *p_vout, picture_t *p_pic,
DirectXUnlockSurface( p_vout, &front_pic ); DirectXUnlockSurface( p_vout, &front_pic );
} }
E_(DirectXUpdateOverlay)( p_vout ); DirectDrawUpdateOverlay( p_vout );
I_OUTPUTPICTURES = 1; I_OUTPUTPICTURES = 1;
msg_Dbg( p_vout, "YUV overlay created successfully" ); msg_Dbg( p_vout, "YUV overlay created successfully" );
} }
......
...@@ -57,6 +57,13 @@ ...@@ -57,6 +57,13 @@
#include "vlc_keys.h" #include "vlc_keys.h"
#include "vout.h" #include "vout.h"
#if defined(UNDER_CE) && !defined(__PLUGIN__) /*FIXME*/
# define SHFS_SHOWSIPBUTTON 0x0004
# define SHFS_HIDESIPBUTTON 0x0008
# define MENU_HEIGHT 26
BOOL SHFullScreen(HWND hwndRequester, DWORD dwState);
#endif
/***************************************************************************** /*****************************************************************************
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
...@@ -82,14 +89,14 @@ static void DirectXPopupMenu( event_thread_t *p_event, vlc_bool_t b_open ) ...@@ -82,14 +89,14 @@ static void DirectXPopupMenu( event_thread_t *p_event, vlc_bool_t b_open )
static int DirectXConvertKey( int i_key ); static int DirectXConvertKey( int i_key );
/***************************************************************************** /*****************************************************************************
* DirectXEventThread: Create video window & handle its messages * EventThread: Create video window & handle its messages
***************************************************************************** *****************************************************************************
* This function creates a video window and then enters an infinite loop * This function creates a video window and then enters an infinite loop
* that handles the messages sent to that window. * that handles the messages sent to that window.
* The main goal of this thread is to isolate the Win32 PeekMessage function * The main goal of this thread is to isolate the Win32 PeekMessage function
* because this one can block for a long time. * because this one can block for a long time.
*****************************************************************************/ *****************************************************************************/
void E_(DirectXEventThread)( event_thread_t *p_event ) void E_(EventThread)( event_thread_t *p_event )
{ {
MSG msg; MSG msg;
POINT old_mouse_pos = {0,0}, mouse_pos; POINT old_mouse_pos = {0,0}, mouse_pos;
...@@ -112,6 +119,7 @@ void E_(DirectXEventThread)( event_thread_t *p_event ) ...@@ -112,6 +119,7 @@ void E_(DirectXEventThread)( event_thread_t *p_event )
/* Signal the creation of the window */ /* Signal the creation of the window */
vlc_thread_ready( p_event ); vlc_thread_ready( p_event );
#ifndef UNDER_CE
/* Set power management stuff */ /* Set power management stuff */
if( (hkernel32 = GetModuleHandle( _T("KERNEL32") ) ) ) if( (hkernel32 = GetModuleHandle( _T("KERNEL32") ) ) )
{ {
...@@ -126,6 +134,7 @@ void E_(DirectXEventThread)( event_thread_t *p_event ) ...@@ -126,6 +134,7 @@ void E_(DirectXEventThread)( event_thread_t *p_event )
else else
msg_Dbg( p_event, "no support for SetThreadExecutionState()" ); msg_Dbg( p_event, "no support for SetThreadExecutionState()" );
} }
#endif
/* Main loop */ /* Main loop */
/* GetMessage will sleep if there's no message in the queue */ /* GetMessage will sleep if there's no message in the queue */
...@@ -307,6 +316,12 @@ void E_(DirectXEventThread)( event_thread_t *p_event ) ...@@ -307,6 +316,12 @@ void E_(DirectXEventThread)( event_thread_t *p_event )
{ {
if( val.psz_string ) free( val.psz_string ); if( val.psz_string ) free( val.psz_string );
#ifdef MODULE_NAME_IS_wingdi
val.psz_string = strdup( VOUT_TITLE " (WinGDI output)" );
#endif
#ifdef MODULE_NAME_IS_wingapi
val.psz_string = strdup( VOUT_TITLE " (WinGAPI output)" );
#endif
#ifdef MODULE_NAME_IS_glwin32 #ifdef MODULE_NAME_IS_glwin32
val.psz_string = strdup( VOUT_TITLE " (OpenGL output)" ); val.psz_string = strdup( VOUT_TITLE " (OpenGL output)" );
#endif #endif
...@@ -315,11 +330,11 @@ void E_(DirectXEventThread)( event_thread_t *p_event ) ...@@ -315,11 +330,11 @@ void E_(DirectXEventThread)( event_thread_t *p_event )
#endif #endif
#ifdef MODULE_NAME_IS_vout_directx #ifdef MODULE_NAME_IS_vout_directx
if( p_event->p_vout->p_sys->b_using_overlay ) val.psz_string = if( p_event->p_vout->p_sys->b_using_overlay ) val.psz_string =
strdup( VOUT_TITLE " (hardware YUV overlay DirectX output)" ); strdup( VOUT_TITLE " (hardware YUV overlay DirectX output)" );
else if( p_event->p_vout->p_sys->b_hw_yuv ) val.psz_string = else if( p_event->p_vout->p_sys->b_hw_yuv ) val.psz_string =
strdup( VOUT_TITLE " (hardware YUV DirectX output)" ); strdup( VOUT_TITLE " (hardware YUV DirectX output)" );
else val.psz_string = else val.psz_string =
strdup( VOUT_TITLE " (software RGB DirectX output)" ); strdup( VOUT_TITLE " (software RGB DirectX output)" );
#endif #endif
} }
...@@ -585,13 +600,13 @@ static void DirectXCloseWindow( vout_thread_t *p_vout ) ...@@ -585,13 +600,13 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
} }
/***************************************************************************** /*****************************************************************************
* DirectXUpdateRects: update clipping rectangles * UpdateRects: update clipping rectangles
***************************************************************************** *****************************************************************************
* This function is called when the window position or size are changed, and * This function is called when the window position or size are changed, and
* its job is to update the source and destination RECTs used to display the * its job is to update the source and destination RECTs used to display the
* picture. * picture.
*****************************************************************************/ *****************************************************************************/
void E_(DirectXUpdateRects)( vout_thread_t *p_vout, vlc_bool_t b_force ) void E_(UpdateRects)( vout_thread_t *p_vout, vlc_bool_t b_force )
{ {
#define rect_src p_vout->p_sys->rect_src #define rect_src p_vout->p_sys->rect_src
#define rect_src_clipped p_vout->p_sys->rect_src_clipped #define rect_src_clipped p_vout->p_sys->rect_src_clipped
...@@ -682,7 +697,7 @@ void E_(DirectXUpdateRects)( vout_thread_t *p_vout, vlc_bool_t b_force ) ...@@ -682,7 +697,7 @@ void E_(DirectXUpdateRects)( vout_thread_t *p_vout, vlc_bool_t b_force )
} }
#else /* MODULE_NAME_IS_vout_directx */ #else /* MODULE_NAME_IS_vout_directx */
/* AFAIK, there are no clipping constraints in Direct3D or OpenGL */ /* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
rect_dest_clipped = rect_dest; rect_dest_clipped = rect_dest;
#endif #endif
...@@ -742,7 +757,7 @@ void E_(DirectXUpdateRects)( vout_thread_t *p_vout, vlc_bool_t b_force ) ...@@ -742,7 +757,7 @@ void E_(DirectXUpdateRects)( vout_thread_t *p_vout, vlc_bool_t b_force )
rect_dest_clipped.bottom -= p_vout->p_sys->rect_display.top; rect_dest_clipped.bottom -= p_vout->p_sys->rect_display.top;
if( p_vout->p_sys->b_using_overlay ) if( p_vout->p_sys->b_using_overlay )
E_(DirectXUpdateOverlay)( p_vout ); DirectDrawUpdateOverlay( p_vout );
#endif #endif
/* Signal the change in size/position */ /* Signal the change in size/position */
...@@ -788,6 +803,7 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -788,6 +803,7 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
} }
} }
#ifndef UNDER_CE
/* Catch the screensaver and the monitor turn-off */ /* Catch the screensaver and the monitor turn-off */
if( message == WM_SYSCOMMAND && if( message == WM_SYSCOMMAND &&
( (wParam & 0xFFF0) == SC_SCREENSAVE || (wParam & 0xFFF0) == SC_MONITORPOWER ) ) ( (wParam & 0xFFF0) == SC_SCREENSAVE || (wParam & 0xFFF0) == SC_MONITORPOWER ) )
...@@ -795,6 +811,7 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -795,6 +811,7 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
//if( p_vout ) msg_Dbg( p_vout, "WinProc WM_SYSCOMMAND screensaver" ); //if( p_vout ) msg_Dbg( p_vout, "WinProc WM_SYSCOMMAND screensaver" );
return 0; /* this stops them from happening */ return 0; /* this stops them from happening */
} }
#endif
if( hwnd == p_vout->p_sys->hvideownd ) if( hwnd == p_vout->p_sys->hvideownd )
{ {
...@@ -841,7 +858,7 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -841,7 +858,7 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
{ {
case WM_WINDOWPOSCHANGED: case WM_WINDOWPOSCHANGED:
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
return 0; return 0;
/* the user wants to close the window */ /* the user wants to close the window */
...@@ -889,6 +906,50 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -889,6 +906,50 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
case WM_ERASEBKGND: case WM_ERASEBKGND:
return DefWindowProc(hwnd, message, wParam, lParam); return DefWindowProc(hwnd, message, wParam, lParam);
case WM_KILLFOCUS:
#ifdef MODULE_NAME_IS_wingapi
p_vout->p_sys->b_focus = VLC_FALSE;
if( !p_vout->p_sys->b_parent_focus ) GXSuspend();
#endif
#ifdef UNDER_CE
if( hWnd == p_vout->p_sys->hfswnd )
{
HWND htbar = FindWindow( _T("HHTaskbar"), NULL );
ShowWindow( htbar, SW_SHOW );
}
if( !p_vout->p_sys->hparent ||
hWnd == p_vout->p_sys->hfswnd )
{
SHFullScreen( hWnd, SHFS_SHOWSIPBUTTON );
}
#endif
return 0;
case WM_SETFOCUS:
#ifdef MODULE_NAME_IS_wingapi
p_vout->p_sys->b_focus = VLC_TRUE;
GXResume();
#endif
#ifdef UNDER_CE
if( p_vout->p_sys->hparent &&
hWnd != p_vout->p_sys->hfswnd && p_vout->b_fullscreen )
p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
if( hWnd == p_vout->p_sys->hfswnd )
{
HWND htbar = FindWindow( _T("HHTaskbar"), NULL );
ShowWindow( htbar, SW_HIDE );
}
if( !p_vout->p_sys->hparent ||
hWnd == p_vout->p_sys->hfswnd )
{
SHFullScreen( hWnd, SHFS_HIDESIPBUTTON );
}
#endif
return 0;
default: default:
//msg_Dbg( p_vout, "WinProc WM Default %i", message ); //msg_Dbg( p_vout, "WinProc WM Default %i", message );
break; break;
...@@ -1063,6 +1124,15 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args ) ...@@ -1063,6 +1124,15 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args )
p_vout->p_sys->b_on_top_change = VLC_TRUE; p_vout->p_sys->b_on_top_change = VLC_TRUE;
return VLC_SUCCESS; return VLC_SUCCESS;
#ifdef MODULE_NAME_IS_wingapi
case VOUT_SET_FOCUS:
b_bool = va_arg( args, vlc_bool_t );
p_vout->p_sys->b_parent_focus = b_bool;
if( b_bool ) GXResume();
else if( !p_vout->p_sys->b_focus ) GXSuspend();
return VLC_SUCCESS;
#endif
default: default:
return vout_vaControlDefault( p_vout, i_query, args ); return vout_vaControlDefault( p_vout, i_query, args );
} }
......
...@@ -108,7 +108,6 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -108,7 +108,6 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL; 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->hparent = p_vout->p_sys->hfswnd = NULL;
p_vout->p_sys->i_changes = 0; p_vout->p_sys->i_changes = 0;
p_vout->p_sys->b_wallpaper = 0;
vlc_mutex_init( p_vout, &p_vout->p_sys->lock ); vlc_mutex_init( p_vout, &p_vout->p_sys->lock );
SetRectEmpty( &p_vout->p_sys->rect_display ); SetRectEmpty( &p_vout->p_sys->rect_display );
SetRectEmpty( &p_vout->p_sys->rect_parent ); SetRectEmpty( &p_vout->p_sys->rect_parent );
...@@ -122,21 +121,21 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -122,21 +121,21 @@ static int OpenVideo( vlc_object_t *p_this )
p_vout->p_sys->i_window_width = p_vout->i_window_width; p_vout->p_sys->i_window_width = p_vout->i_window_width;
p_vout->p_sys->i_window_height = p_vout->i_window_height; p_vout->p_sys->i_window_height = p_vout->i_window_height;
/* Create the DirectXEventThread, this thread is created by us to isolate /* Create the Vout EventThread, this thread is created by us to isolate
* the Win32 PeekMessage function calls. We want to do this because * the Win32 PeekMessage function calls. We want to do this because
* Windows can stay blocked inside this call for a long time, and when * Windows can stay blocked inside this call for a long time, and when
* this happens it thus blocks vlc's video_output thread. * this happens it thus blocks vlc's video_output thread.
* DirectXEventThread will take care of the creation of the video * Vout EventThread will take care of the creation of the video
* window (because PeekMessage has to be called from the same thread which * window (because PeekMessage has to be called from the same thread which
* created the window). */ * created the window). */
msg_Dbg( p_vout, "creating DirectXEventThread" ); msg_Dbg( p_vout, "creating Vout EventThread" );
p_vout->p_sys->p_event = p_vout->p_sys->p_event =
vlc_object_create( p_vout, sizeof(event_thread_t) ); vlc_object_create( p_vout, sizeof(event_thread_t) );
p_vout->p_sys->p_event->p_vout = p_vout; p_vout->p_sys->p_event->p_vout = p_vout;
if( vlc_thread_create( p_vout->p_sys->p_event, "DirectX Events Thread", if( vlc_thread_create( p_vout->p_sys->p_event, "Vout Events Thread",
E_(DirectXEventThread), 0, 1 ) ) E_(EventThread), 0, 1 ) )
{ {
msg_Err( p_vout, "cannot create DirectXEventThread" ); msg_Err( p_vout, "cannot create Vout EventThread" );
vlc_object_destroy( p_vout->p_sys->p_event ); vlc_object_destroy( p_vout->p_sys->p_event );
p_vout->p_sys->p_event = NULL; p_vout->p_sys->p_event = NULL;
goto error; goto error;
...@@ -144,13 +143,13 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -144,13 +143,13 @@ static int OpenVideo( vlc_object_t *p_this )
if( p_vout->p_sys->p_event->b_error ) if( p_vout->p_sys->p_event->b_error )
{ {
msg_Err( p_vout, "DirectXEventThread failed" ); msg_Err( p_vout, "Vout EventThread failed" );
goto error; goto error;
} }
vlc_object_attach( p_vout->p_sys->p_event, p_vout ); vlc_object_attach( p_vout->p_sys->p_event, p_vout );
msg_Dbg( p_vout, "DirectXEventThread running" ); msg_Dbg( p_vout, "Vout EventThread running" );
/* Variable to indicate if the window should be on top of others */ /* Variable to indicate if the window should be on top of others */
/* Trigger a callback right now */ /* Trigger a callback right now */
...@@ -225,10 +224,10 @@ static void CloseVideo( vlc_object_t *p_this ) ...@@ -225,10 +224,10 @@ static void CloseVideo( vlc_object_t *p_this )
{ {
vlc_object_detach( p_vout->p_sys->p_event ); vlc_object_detach( p_vout->p_sys->p_event );
/* Kill DirectXEventThread */ /* Kill Vout EventThread */
p_vout->p_sys->p_event->b_die = VLC_TRUE; p_vout->p_sys->p_event->b_die = VLC_TRUE;
/* we need to be sure DirectXEventThread won't stay stuck in /* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */ * GetMessage, so we send a fake message */
if( p_vout->p_sys->hwnd ) if( p_vout->p_sys->hwnd )
{ {
...@@ -312,7 +311,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -312,7 +311,7 @@ static int Manage( vout_thread_t *p_vout )
p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num; p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den; p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
p_vout->output.i_aspect = p_vout->fmt_in.i_aspect; p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
E_(DirectXUpdateRects)( p_vout, VLC_TRUE ); E_(UpdateRects)( p_vout, VLC_TRUE );
} }
/* We used to call the Win32 PeekMessage function here to read the window /* We used to call the Win32 PeekMessage function here to read the window
......
/***************************************************************************** /*****************************************************************************
* vout.h: Windows DirectX video output header file * vout.h: Windows video output header file
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2004 the VideoLAN team * Copyright (C) 2001-2004 the VideoLAN team
* $Id$ * $Id$
* *
* Authors: Gildas Bazin <gbazin@videolan.org> * Authors: Gildas Bazin <gbazin@videolan.org>
* Damien Fouilleul <damienf@videolan.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -22,7 +23,7 @@ ...@@ -22,7 +23,7 @@
*****************************************************************************/ *****************************************************************************/
/***************************************************************************** /*****************************************************************************
* event_thread_t: DirectX event thread * event_thread_t: event thread
*****************************************************************************/ *****************************************************************************/
typedef struct event_thread_t typedef struct event_thread_t
{ {
...@@ -33,10 +34,10 @@ typedef struct event_thread_t ...@@ -33,10 +34,10 @@ typedef struct event_thread_t
} event_thread_t; } event_thread_t;
/***************************************************************************** /*****************************************************************************
* vout_sys_t: video output DirectX method descriptor * vout_sys_t: video output method descriptor
***************************************************************************** *****************************************************************************
* This structure is part of the video output thread descriptor. * This structure is part of the video output thread descriptor.
* It describes the DirectX specific properties of an output thread. * It describes the module specific properties of an output thread.
*****************************************************************************/ *****************************************************************************/
struct vout_sys_t struct vout_sys_t
{ {
...@@ -75,13 +76,15 @@ struct vout_sys_t ...@@ -75,13 +76,15 @@ struct vout_sys_t
/* Misc */ /* Misc */
vlc_bool_t b_on_top_change; vlc_bool_t b_on_top_change;
vlc_bool_t b_wallpaper; #ifndef UNDER_CE
/* screensaver system settings to be restored when vout is closed */ /* screensaver system settings to be restored when vout is closed */
UINT i_spi_lowpowertimeout; UINT i_spi_lowpowertimeout;
UINT i_spi_powerofftimeout; UINT i_spi_powerofftimeout;
UINT i_spi_screensavetimeout; UINT i_spi_screensavetimeout;
#endif
/* Coordinates of src and dest images (used when blitting to display) */ /* Coordinates of src and dest images (used when blitting to display) */
RECT rect_src; RECT rect_src;
RECT rect_src_clipped; RECT rect_src_clipped;
...@@ -90,6 +93,7 @@ struct vout_sys_t ...@@ -90,6 +93,7 @@ struct vout_sys_t
vlc_bool_t b_hw_yuv; /* Should we use hardware YUV->RGB conversions */ vlc_bool_t b_hw_yuv; /* Should we use hardware YUV->RGB conversions */
#ifdef MODULE_NAME_IS_vout_directx #ifdef MODULE_NAME_IS_vout_directx
/* Overlay alignment restrictions */ /* Overlay alignment restrictions */
int i_align_src_boundary; int i_align_src_boundary;
...@@ -97,6 +101,8 @@ struct vout_sys_t ...@@ -97,6 +101,8 @@ struct vout_sys_t
int i_align_dest_boundary; int i_align_dest_boundary;
int i_align_dest_size; int i_align_dest_size;
vlc_bool_t b_wallpaper; /* show as desktop wallpaper ? */
vlc_bool_t b_using_overlay; /* Are we using an overlay surface */ vlc_bool_t b_using_overlay; /* Are we using an overlay surface */
vlc_bool_t b_use_sysmem; /* Should we use system memory for surfaces */ vlc_bool_t b_use_sysmem; /* Should we use system memory for surfaces */
vlc_bool_t b_3buf_overlay; /* Should we use triple buffered overlays */ vlc_bool_t b_3buf_overlay; /* Should we use triple buffered overlays */
...@@ -133,20 +139,62 @@ struct vout_sys_t ...@@ -133,20 +139,62 @@ struct vout_sys_t
LPDIRECT3DVERTEXBUFFER9 p_d3dvtc; LPDIRECT3DVERTEXBUFFER9 p_d3dvtc;
#endif #endif
#ifdef MODULE_NAME_IS_wingdi
int i_depth;
/* 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;
#endif
#ifdef MODULE_NAME_IS_wingapi
int i_depth;
int render_width;
int render_height;
vlc_bool_t b_focus;
vlc_bool_t b_parent_focus;
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
#ifndef UNDER_CE
/* suspend display */
vlc_bool_t b_suspend_display;
#endif
event_thread_t *p_event; event_thread_t *p_event;
vlc_mutex_t lock; vlc_mutex_t lock;
}; };
/***************************************************************************** /*****************************************************************************
* Prototypes from vout.c * Prototypes from directx.c
*****************************************************************************/ *****************************************************************************/
int E_(DirectXUpdateOverlay)( vout_thread_t *p_vout ); int DirectDrawUpdateOverlay( vout_thread_t *p_vout );
/***************************************************************************** /*****************************************************************************
* Prototypes from events.c * Prototypes from events.c
*****************************************************************************/ *****************************************************************************/
void E_(DirectXEventThread) ( event_thread_t *p_event ); void E_(EventThread) ( event_thread_t *p_event );
void E_(DirectXUpdateRects) ( vout_thread_t *p_vout, vlc_bool_t b_force ); void E_(UpdateRects) ( vout_thread_t *p_vout, vlc_bool_t b_force );
void Win32ToggleFullscreen ( vout_thread_t *p_vout ); void Win32ToggleFullscreen ( vout_thread_t *p_vout );
/***************************************************************************** /*****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* wingdi.c : Win32 / WinCE GDI video output plugin for vlc * wingdi.c : Win32 / WinCE GDI video output plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 the VideoLAN team * Copyright (C) 2002 the VideoLAN team
* $Id$ * $Id: wingdi.c 18074 2006-11-26 16:26:44Z zorglub $
* *
* Authors: Gildas Bazin <gbazin@videolan.org> * Authors: Gildas Bazin <gbazin@videolan.org>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -35,16 +35,7 @@ ...@@ -35,16 +35,7 @@
#include <commctrl.h> #include <commctrl.h>
#define SHFS_SHOWSIPBUTTON 0x0004 #include "vout.h"
#define SHFS_HIDESIPBUTTON 0x0008
#if defined(UNDER_CE) && !defined(__PLUGIN__) /*FIXME*/
# 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 #ifdef MODULE_NAME_IS_wingapi
typedef struct GXDisplayProperties { typedef struct GXDisplayProperties {
...@@ -111,101 +102,26 @@ static void End ( vout_thread_t * ); ...@@ -111,101 +102,26 @@ static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * ); static int Manage ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * ); static void Render ( vout_thread_t *, picture_t * );
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
static void FirstDisplayGAPI( vout_thread_t *, picture_t * );
static void DisplayGAPI( vout_thread_t *, picture_t * ); static void DisplayGAPI( vout_thread_t *, picture_t * );
static int GAPILockSurface( vout_thread_t *, picture_t * ); static int GAPILockSurface( vout_thread_t *, picture_t * );
static int GAPIUnlockSurface( vout_thread_t *, picture_t * ); static int GAPIUnlockSurface( vout_thread_t *, picture_t * );
#else #else
static void FirstDisplayGDI( vout_thread_t *, picture_t * );
static void DisplayGDI( vout_thread_t *, picture_t * ); static void DisplayGDI( vout_thread_t *, picture_t * );
#endif #endif
static void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * ); static 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 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 i_window_style;
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 #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 GXSuspend p_vout->p_sys->GXSuspend
# define GXResume p_vout->p_sys->GXResume # define GXResume p_vout->p_sys->GXResume
#else
# define GXSuspend()
# define GXResume()
#endif #endif
#define DX_POSITION_CHANGE 0x1000 #define DX_POSITION_CHANGE 0x1000
...@@ -238,6 +154,7 @@ static int OpenVideo ( vlc_object_t *p_this ) ...@@ -238,6 +154,7 @@ static int OpenVideo ( vlc_object_t *p_this )
p_vout->p_sys = (vout_sys_t *)malloc( sizeof(vout_sys_t) ); p_vout->p_sys = (vout_sys_t *)malloc( sizeof(vout_sys_t) );
if( !p_vout->p_sys ) return VLC_ENOMEM; if( !p_vout->p_sys ) return VLC_ENOMEM;
memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
/* Load GAPI */ /* Load GAPI */
...@@ -286,35 +203,102 @@ static int OpenVideo ( vlc_object_t *p_this ) ...@@ -286,35 +203,102 @@ static int OpenVideo ( vlc_object_t *p_this )
return VLC_ENOMEM; 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_init = Init;
p_vout->pf_end = End; p_vout->pf_end = End;
p_vout->pf_manage = Manage; p_vout->pf_manage = Manage;
p_vout->pf_render = Render; p_vout->pf_render = Render;
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
p_vout->pf_display = DisplayGAPI; p_vout->pf_display = FirstDisplayGAPI;
p_vout->p_sys->b_focus = 0;
p_vout->p_sys->b_parent_focus = 0;
#else #else
p_vout->pf_display = DisplayGDI; p_vout->pf_display = FirstDisplayGDI;
#endif #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; p_vout->p_sys->i_changes = 0;
vlc_mutex_init( p_vout, &p_vout->p_sys->lock );
SetRectEmpty( &p_vout->p_sys->rect_display );
SetRectEmpty( &p_vout->p_sys->rect_parent );
p_vout->p_sys->b_focus = 0; var_Create( p_vout, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
p_vout->p_sys->b_parent_focus = 0; 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();
/* 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",
E_(EventThread), 0, 1 ) )
{
msg_Err( p_vout, "cannot create Vout EventThread" );
vlc_object_destroy( 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; return VLC_SUCCESS;
error:
CloseVideo( VLC_OBJECT(p_vout) );
return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
...@@ -324,17 +308,50 @@ static void CloseVideo ( vlc_object_t *p_this ) ...@@ -324,17 +308,50 @@ static void CloseVideo ( vlc_object_t *p_this )
{ {
vout_thread_t * p_vout = (vout_thread_t *)p_this; vout_thread_t * p_vout = (vout_thread_t *)p_this;
p_vout->p_sys->p_event->b_die = VLC_TRUE; if( p_vout->p_sys->p_event )
PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0 ); {
vlc_thread_join( p_vout->p_sys->p_event ); vlc_object_detach( p_vout->p_sys->p_event );
/* Kill Vout EventThread */
p_vout->p_sys->p_event->b_die = VLC_TRUE;
/* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */
if( p_vout->p_sys->hwnd )
{
PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
}
vlc_thread_join( p_vout->p_sys->p_event );
vlc_object_destroy( p_vout->p_sys->p_event );
}
vlc_mutex_destroy( &p_vout->p_sys->lock );
#ifndef UNDER_CE
/* restore screensaver system settings */
if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) {
SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT,
p_vout->p_sys->i_spi_lowpowertimeout, NULL, 0);
}
if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) {
SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT,
p_vout->p_sys->i_spi_powerofftimeout, NULL, 0);
}
if( 0 != p_vout->p_sys->i_spi_screensavetimeout ) {
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,
p_vout->p_sys->i_spi_screensavetimeout, NULL, 0);
}
#endif
#ifdef MODULE_NAME_IS_wingapi #ifdef MODULE_NAME_IS_wingapi
FreeLibrary( p_vout->p_sys->gapi_dll ); FreeLibrary( p_vout->p_sys->gapi_dll );
#endif #endif
var_Destroy( p_vout->p_sys->p_event, "p_vout" ); if( p_vout->p_sys )
vlc_object_destroy( p_vout->p_sys->p_event ); {
free( p_vout->p_sys ); free( p_vout->p_sys );
p_vout->p_sys = NULL;
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -344,14 +361,14 @@ static int Init( vout_thread_t *p_vout ) ...@@ -344,14 +361,14 @@ static int Init( vout_thread_t *p_vout )
{ {
picture_t *p_pic; picture_t *p_pic;
/* Initialize offscreen buffer */
InitBuffers( p_vout );
p_vout->p_sys->rect_display.left = 0; p_vout->p_sys->rect_display.left = 0;
p_vout->p_sys->rect_display.top = 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.right = GetSystemMetrics(SM_CXSCREEN);
p_vout->p_sys->rect_display.bottom = GetSystemMetrics(SM_CYSCREEN); 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; I_OUTPUTPICTURES = 0;
/* Initialize the output structure */ /* Initialize the output structure */
...@@ -428,6 +445,10 @@ static int Init( vout_thread_t *p_vout ) ...@@ -428,6 +445,10 @@ static int Init( vout_thread_t *p_vout )
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES++ ] = p_pic; PP_OUTPUTPICTURE[ I_OUTPUTPICTURES++ ] = p_pic;
/* Change the window title bar text */
PostMessage( p_vout->p_sys->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
E_(UpdateRects)( p_vout, VLC_TRUE );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -436,6 +457,12 @@ static int Init( vout_thread_t *p_vout ) ...@@ -436,6 +457,12 @@ static int Init( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void End( vout_thread_t *p_vout ) static void End( vout_thread_t *p_vout )
{ {
#ifdef MODULE_NAME_IS_wingapi
GXCloseDisplay();
#else
DeleteDC( p_vout->p_sys->off_dc );
DeleteObject( p_vout->p_sys->off_bitmap );
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -446,17 +473,16 @@ static void End( vout_thread_t *p_vout ) ...@@ -446,17 +473,16 @@ static void End( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static int Manage( vout_thread_t *p_vout ) static int Manage( vout_thread_t *p_vout )
{ {
#ifndef UNDER_CE
WINDOWPLACEMENT window_placement;
#endif
/* If we do not control our window, we check for geometry changes /* If we do not control our window, we check for geometry changes
* ourselves because the parent might not send us its events. */ * ourselves because the parent might not send us its events. */
vlc_mutex_lock( &p_vout->p_sys->lock );
if( p_vout->p_sys->hparent && !p_vout->b_fullscreen ) if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
{ {
RECT rect_parent; RECT rect_parent;
POINT point; POINT point;
vlc_mutex_unlock( &p_vout->p_sys->lock );
GetClientRect( p_vout->p_sys->hparent, &rect_parent ); GetClientRect( p_vout->p_sys->hparent, &rect_parent );
point.x = point.y = 0; point.x = point.y = 0;
ClientToScreen( p_vout->p_sys->hparent, &point ); ClientToScreen( p_vout->p_sys->hparent, &point );
...@@ -485,6 +511,36 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -485,6 +511,36 @@ static int Manage( vout_thread_t *p_vout )
i_x, i_y, i_width, i_height, 0 ); i_x, i_y, i_width, i_height, 0 );
} }
} }
else
{
vlc_mutex_unlock( &p_vout->p_sys->lock );
}
/* Check for cropping / aspect changes */
if( p_vout->i_changes & VOUT_CROP_CHANGE ||
p_vout->i_changes & VOUT_ASPECT_CHANGE )
{
p_vout->i_changes &= ~VOUT_CROP_CHANGE;
p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;
p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;
p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;
p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;
p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;
p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
E_(UpdateRects)( p_vout, VLC_TRUE );
}
/*
* Position Change
*/
if( p_vout->p_sys->i_changes & DX_POSITION_CHANGE )
{
p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;
}
/* We used to call the Win32 PeekMessage function here to read the window /* We used to call the Win32 PeekMessage function here to read the window
* messages. But since window can stay blocked into this function for a * messages. But since window can stay blocked into this function for a
...@@ -497,100 +553,71 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -497,100 +553,71 @@ static int Manage( vout_thread_t *p_vout )
if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE
|| p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE ) || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )
{ {
int i_style = 0; Win32ToggleFullscreen( p_vout );
vlc_value_t val;
HWND hwnd = (p_vout->p_sys->hparent && p_vout->p_sys->hfswnd) ? p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
p_vout->p_sys->hfswnd : p_vout->p_sys->hwnd; p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
}
p_vout->b_fullscreen = ! p_vout->b_fullscreen; /*
* Pointer change
*/
if( p_vout->b_fullscreen && !p_vout->p_sys->b_cursor_hidden &&
(mdate() - p_vout->p_sys->i_lastmoved) > 5000000 )
{
POINT point;
HWND hwnd;
/* We need to switch between Maximized and Normal sized window */ /* Hide the cursor only if it is inside our window */
#ifndef UNDER_CE GetCursorPos( &point );
window_placement.length = sizeof(WINDOWPLACEMENT); hwnd = WindowFromPoint(point);
GetWindowPlacement( hwnd, &window_placement ); if( hwnd == p_vout->p_sys->hwnd || hwnd == p_vout->p_sys->hvideownd )
#endif
if( p_vout->b_fullscreen )
{ {
#ifndef UNDER_CE PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
/* Change window style, no borders and no title bar */
int i_style = WS_CLIPCHILDREN | WS_VISIBLE;
SetWindowLong( hwnd, GWL_STYLE, i_style );
if( p_vout->p_sys->hparent )
{
/* Retrieve current window position so fullscreen will happen
* on the right screen */
POINT point = {0,0};
RECT rect;
ClientToScreen( p_vout->p_sys->hwnd, &point );
GetClientRect( p_vout->p_sys->hwnd, &rect );
SetWindowPos( hwnd, 0, point.x, point.y,
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED );
GetWindowPlacement( hwnd, &window_placement );
}
/* Maximize window */
window_placement.showCmd = SW_SHOWMAXIMIZED;
SetWindowPlacement( hwnd, &window_placement );
SetWindowPos( hwnd, 0, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
#endif
if( p_vout->p_sys->hparent )
{
RECT rect;
GetClientRect( hwnd, &rect );
SetParent( p_vout->p_sys->hwnd, hwnd );
SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED );
}
ShowWindow( hwnd, SW_SHOW );
SetForegroundWindow( hwnd );
} }
else else
{ {
/* Change window style, no borders and no title bar */ p_vout->p_sys->i_lastmoved = mdate();
//SetWindowLong( hwnd, GWL_STYLE, p_vout->p_sys->i_window_style ); }
}
#ifndef UNDER_CE /*
/* Normal window */ * "Always on top" status change
window_placement.showCmd = SW_SHOWNORMAL; */
SetWindowPlacement( hwnd, &window_placement ); if( p_vout->p_sys->b_on_top_change )
SetWindowPos( hwnd, 0, 0, 0, 0, 0, {
SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); vlc_value_t val;
#endif HMENU hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
if( p_vout->p_sys->hparent ) var_Get( p_vout, "video-on-top", &val );
{
RECT rect;
GetClientRect( p_vout->p_sys->hparent, &rect );
SetParent( p_vout->p_sys->hwnd, p_vout->p_sys->hparent );
SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED );
ShowWindow( hwnd, SW_HIDE );
SetForegroundWindow( p_vout->p_sys->hparent );
}
/* Make sure the mouse cursor is displayed */
//PostMessage( p_vout->p_sys->hwnd, WM_VLC_SHOW_MOUSE, 0, 0 );
}
/* Change window style, borders and title bar */ /* Set the window on top if necessary */
ShowWindow( p_vout->p_sys->hwnd, SW_SHOW ); if( val.b_bool && !( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
UpdateWindow( p_vout->p_sys->hwnd ); & WS_EX_TOPMOST ) )
{
CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
MF_BYCOMMAND | MFS_CHECKED );
SetWindowPos( p_vout->p_sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE );
}
else
/* The window shouldn't be on top */
if( !val.b_bool && ( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
& WS_EX_TOPMOST ) )
{
CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
MF_BYCOMMAND | MFS_UNCHECKED );
SetWindowPos( p_vout->p_sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE );
}
/* Update the object variable and trigger callback */ p_vout->p_sys->b_on_top_change = VLC_FALSE;
val.b_bool = p_vout->b_fullscreen; }
var_Set( p_vout, "fullscreen", val );
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; /* Check if the event thread is still running */
p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE; if( p_vout->p_sys->p_event->b_die )
{
return VLC_EGENERIC; /* exit */
} }
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -640,8 +667,30 @@ static void DisplayGDI( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -640,8 +667,30 @@ static void DisplayGDI( vout_thread_t *p_vout, picture_t *p_pic )
rect_src_clipped.top, SRCCOPY ); rect_src_clipped.top, SRCCOPY );
} }
ReleaseDC( p_sys->hwnd, hdc ); ReleaseDC( p_sys->hvideownd, hdc );
}
static void FirstDisplayGDI( vout_thread_t *p_vout, picture_t *p_pic )
{
/*
** Video window is initially hidden, show it now since we got a
** picture to show.
*/
SetWindowPos( p_vout->p_sys->hvideownd, 0, 0, 0, 0, 0,
SWP_ASYNCWINDOWPOS|
SWP_FRAMECHANGED|
SWP_SHOWWINDOW|
SWP_NOMOVE|
SWP_NOSIZE|
SWP_NOZORDER );
/* get initial picture presented */
DisplayGDI(p_vout, p_pic);
/* use and restores proper display function for further pictures */
p_vout->pf_display = DisplayGDI;
} }
#else #else
static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic ) static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic )
...@@ -651,13 +700,6 @@ static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -651,13 +700,6 @@ static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic )
RECT video_rect; RECT video_rect;
POINT point; POINT point;
/* Undo the display */
if( ( GetForegroundWindow() != GetParent(p_sys->hwnd) ) ||
( p_sys->b_video_display == VLC_FALSE ) )
{
//return VLC_EGENERIC;
}
GetClientRect( p_sys->hwnd, &video_rect); GetClientRect( p_sys->hwnd, &video_rect);
vout_PlacePicture( p_vout, video_rect.right - video_rect.left, vout_PlacePicture( p_vout, video_rect.right - video_rect.left,
video_rect.bottom - video_rect.top, video_rect.bottom - video_rect.top,
...@@ -745,444 +787,41 @@ static int GAPIUnlockSurface( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -745,444 +787,41 @@ static int GAPIUnlockSurface( vout_thread_t *p_vout, picture_t *p_pic )
static void DisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic ) static void DisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic )
{ {
} }
#endif
#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
/*****************************************************************************
* SetPalette: sets an 8 bpp palette
*****************************************************************************/
static void SetPalette( vout_thread_t *p_vout,
uint16_t *red, uint16_t *green, uint16_t *blue )
{
msg_Err( p_vout, "FIXME: SetPalette unimplemented" );
}
/***************************************************************************** static void FirstDisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic )
* EventThread: Event handling thread
*****************************************************************************/
static void EventThread ( vlc_object_t *p_event )
{ {
vout_thread_t *p_vout; /* get initial picture presented through D3D */
vlc_value_t val; DisplayGAPI(p_vout, p_pic);
int i_style;
WNDCLASS wc;
MSG msg;
/* Initialisations */
var_Get( p_event, "p_vout", &val );
p_vout = (vout_thread_t *)val.p_address;
/* Register window class */
memset( &wc, 0, sizeof(wc) );
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = 0;
wc.lpszClassName = _T("VLC WinGDI");
RegisterClass( &wc );
/* Register the video sub-window class */
wc.lpszClassName = _T("VLC WinGDI video"); wc.hIcon = 0;
RegisterClass(&wc);
/* Create output window */
p_vout->p_sys->hparent = (HWND)
vout_RequestWindow( p_vout, &p_vout->p_sys->i_window_x,
&p_vout->p_sys->i_window_y,
(unsigned int *)&p_vout->p_sys->i_window_width,
(unsigned int *)&p_vout->p_sys->i_window_height );
if( p_vout->p_sys->hparent )
ShowWindow( p_vout->p_sys->hparent, SW_SHOW );
if( p_vout->p_sys->hparent )
i_style = WS_VISIBLE|WS_CLIPCHILDREN|WS_CHILD;
else
i_style = WS_OVERLAPPEDWINDOW|WS_SIZEBOX|WS_VISIBLE|WS_CLIPCHILDREN;
p_vout->p_sys->i_window_style = i_style;
p_vout->p_sys->hwnd =
CreateWindow( _T("VLC WinGDI"), _T(VOUT_TITLE), i_style,
(p_vout->p_sys->i_window_x < 0) ? CW_USEDEFAULT :
p_vout->p_sys->i_window_x, /* default X coordinate */
(p_vout->p_sys->i_window_y < 0) ? CW_USEDEFAULT :
p_vout->p_sys->i_window_y, /* default Y coordinate */
p_vout->p_sys->i_window_width,
p_vout->p_sys->i_window_height + 10,
p_vout->p_sys->hparent, NULL,
GetModuleHandle(NULL), (LPVOID)p_vout );
if( !p_vout->p_sys->hwnd )
{
msg_Warn( p_vout, "couldn't create window" );
return;
}
msg_Warn( p_vout, "Created WinGDI window" );
if( p_vout->p_sys->hparent ) /*
{ ** Video window is initially hidden, show it now since we got a
LONG i_style; ** picture to show.
*/
/* We don't want the window owner to overwrite our client area */ SetWindowPos( p_vout->p_sys->hvideownd, 0, 0, 0, 0, 0,
i_style = GetWindowLong( p_vout->p_sys->hparent, GWL_STYLE ); SWP_ASYNCWINDOWPOS|
SWP_FRAMECHANGED|
if( !(i_style & WS_CLIPCHILDREN) ) SWP_SHOWWINDOW|
/* Hmmm, apparently this is a blocking call... */ SWP_NOMOVE|
SetWindowLong( p_vout->p_sys->hparent, GWL_STYLE, SWP_NOSIZE|
i_style | WS_CLIPCHILDREN ); SWP_NOZORDER );
/* Create our fullscreen window */ /* use and restores proper display function for further pictures */
p_vout->p_sys->hfswnd = p_vout->pf_display = DisplayGAPI;
CreateWindowEx( WS_EX_APPWINDOW, _T("VLC WinGDI"),
_T(VOUT_TITLE),
WS_NONAVDONEBUTTON|WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, GetModuleHandle(NULL), (LPVOID)p_vout);
}
/* Display our window */
ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
UpdateWindow( p_vout->p_sys->hwnd );
/* Create video sub-window */
p_vout->p_sys->hvideownd =
CreateWindow( _T("VLC WinGDI video"), _T(""), /* window class */
WS_CHILD | WS_VISIBLE, /* window style */
CW_USEDEFAULT, CW_USEDEFAULT, /* default coordinates */
CW_USEDEFAULT, CW_USEDEFAULT,
p_vout->p_sys->hwnd, /* parent window */
NULL, GetModuleHandle(NULL),
(LPVOID)p_vout ); /* send p_vout to WM_CREATE */
/* Initialize offscreen buffer */
InitBuffers( p_vout );
p_vout->pf_control = Control;
/* Tell the video output we're ready to receive data */
vlc_thread_ready( p_event );
while( !p_event->b_die && GetMessage( &msg, 0, 0, 0 ) )
{
/* Check if we are asked to exit */
if( p_event->b_die ) break;
switch( msg.message )
{
case WM_KEYDOWN:
switch( msg.wParam )
{
case VK_ESCAPE:
p_event->p_libvlc->b_die = VLC_TRUE;
break;
}
TranslateMessage( &msg );
break;
case WM_CHAR:
switch( msg.wParam )
{
case 'q':
case 'Q':
p_event->p_libvlc->b_die = VLC_TRUE;
break;
}
break;
default:
TranslateMessage( &msg );
DispatchMessage( &msg );
break;
}
}
msg_Dbg( p_vout, "CloseWindow" );
#ifdef MODULE_NAME_IS_wingapi
GXCloseDisplay();
#else
DeleteDC( p_vout->p_sys->off_dc );
DeleteObject( p_vout->p_sys->off_bitmap );
#endif
DestroyWindow( p_vout->p_sys->hwnd );
if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd );
if( p_vout->p_sys->hparent )
vout_ReleaseWindow( p_vout, (void *)p_vout->p_sys->hparent );
} }
/*****************************************************************************
* UpdateRects: update clipping rectangles
*****************************************************************************
* This function is called when the window position or size are changed, and
* its job is to update the source and destination RECTs used to display the
* picture.
*****************************************************************************/
static void UpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
{
#define rect_src p_vout->p_sys->rect_src
#define rect_src_clipped p_vout->p_sys->rect_src_clipped
#define rect_dest p_vout->p_sys->rect_dest
#define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
int i_width, i_height, i_x, i_y;
RECT rect;
POINT point;
/* Retrieve the window size */
GetClientRect( p_vout->p_sys->hwnd, &rect );
/* Retrieve the window position */
point.x = point.y = 0;
ClientToScreen( p_vout->p_sys->hwnd, &point );
/* If nothing changed, we can return */
if( !b_force
&& p_vout->p_sys->i_window_width == rect.right
&& p_vout->p_sys->i_window_height == rect.bottom
&& p_vout->p_sys->i_window_x == point.x
&& p_vout->p_sys->i_window_y == point.y )
{
return;
}
/* Update the window position and size */
p_vout->p_sys->i_window_x = point.x;
p_vout->p_sys->i_window_y = point.y;
p_vout->p_sys->i_window_width = rect.right;
p_vout->p_sys->i_window_height = rect.bottom;
vout_PlacePicture( p_vout, rect.right, rect.bottom,
&i_x, &i_y, &i_width, &i_height );
if( p_vout->p_sys->hvideownd )
SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,
i_x, i_y, i_width, i_height, 0 );
/* Destination image position and dimensions */
rect_dest.left = point.x + i_x;
rect_dest.right = rect_dest.left + i_width;
rect_dest.top = point.y + i_y;
rect_dest.bottom = rect_dest.top + i_height;
/* Clip the destination window */
if( !IntersectRect( &rect_dest_clipped, &rect_dest,
&p_vout->p_sys->rect_display ) )
{
SetRectEmpty( &rect_src_clipped );
return;
}
#if 0
msg_Dbg( p_vout, "image_dst_clipped coords: %i,%i,%i,%i",
rect_dest_clipped.left, rect_dest_clipped.top,
rect_dest_clipped.right, rect_dest_clipped.bottom );
#endif #endif
/* the 2 following lines are to fix a bug when clicking on the desktop */
if( (rect_dest_clipped.right - rect_dest_clipped.left)==0 ||
(rect_dest_clipped.bottom - rect_dest_clipped.top)==0 )
{
SetRectEmpty( &rect_src_clipped );
return;
}
/* src image dimensions */
rect_src.left = 0;
rect_src.top = 0;
rect_src.right = p_vout->output.i_width;
rect_src.bottom = p_vout->output.i_height;
/* Clip the source image */
rect_src_clipped.left = (rect_dest_clipped.left - rect_dest.left) *
p_vout->output.i_width / (rect_dest.right - rect_dest.left);
rect_src_clipped.right = p_vout->output.i_width -
(rect_dest.right - rect_dest_clipped.right) * p_vout->output.i_width /
(rect_dest.right - rect_dest.left);
rect_src_clipped.top = (rect_dest_clipped.top - rect_dest.top) *
p_vout->output.i_height / (rect_dest.bottom - rect_dest.top);
rect_src_clipped.bottom = p_vout->output.i_height -
(rect_dest.bottom - rect_dest_clipped.bottom) * p_vout->output.i_height /
(rect_dest.bottom - rect_dest.top);
#if 0
msg_Dbg( p_vout, "image_src_clipped coords: %i,%i,%i,%i",
rect_src_clipped.left, rect_src_clipped.top,
rect_src_clipped.right, rect_src_clipped.bottom );
#endif
/* The destination coordinates need to be relative to the current
* directdraw primary surface (display) */
rect_dest_clipped.left -= p_vout->p_sys->rect_display.left;
rect_dest_clipped.right -= p_vout->p_sys->rect_display.left;
rect_dest_clipped.top -= p_vout->p_sys->rect_display.top;
rect_dest_clipped.bottom -= p_vout->p_sys->rect_display.top;
/* Signal the change in size/position */
p_vout->p_sys->i_changes |= DX_POSITION_CHANGE;
#undef rect_src #undef rect_src
#undef rect_src_clipped #undef rect_src_clipped
#undef rect_dest #undef rect_dest
#undef rect_dest_clipped #undef rect_dest_clipped
}
/***************************************************************************** /*****************************************************************************
* Message handler for the main window * SetPalette: sets an 8 bpp palette
*****************************************************************************/ *****************************************************************************/
static long FAR PASCAL WndProc( HWND hWnd, UINT message, static void SetPalette( vout_thread_t *p_vout,
WPARAM wParam, LPARAM lParam ) uint16_t *red, uint16_t *green, uint16_t *blue )
{ {
vout_thread_t *p_vout; msg_Err( p_vout, "FIXME: SetPalette unimplemented" );
if( message == WM_CREATE )
{
/* Store p_vout for future use */
p_vout = (vout_thread_t *)((CREATESTRUCT *)lParam)->lpCreateParams;
SetWindowLongPtr( hWnd, GWLP_USERDATA, (LONG_PTR)p_vout );
if( p_vout ) msg_Dbg( p_vout, "create: %p", hWnd );
}
else
{
p_vout = (vout_thread_t *)GetWindowLongPtr( hWnd, GWLP_USERDATA );
}
#ifndef UNDER_CE
/* Catch the screensaver and the monitor turn-off */
if( message == WM_SYSCOMMAND &&
( (wParam & 0xFFF0) == SC_SCREENSAVE || (wParam & 0xFFF0) == SC_MONITORPOWER ) )
{
//if( p_vout ) msg_Dbg( p_vout, "WinProc WM_SYSCOMMAND screensaver" );
return 0; /* this stops them from happening */
}
#endif
if( !p_vout )
{
/* Hmmm mozilla does manage somehow to save the pointer to our
* windowproc and still calls it after the vout has been closed. */
return DefWindowProc(hWnd, message, wParam, lParam);
}
if( hWnd != p_vout->p_sys->hwnd &&
hWnd != p_vout->p_sys->hfswnd &&
hWnd != p_vout->p_sys->hvideownd )
return DefWindowProc(hWnd, message, wParam, lParam);
switch( message )
{
case WM_WINDOWPOSCHANGED:
if( hWnd == p_vout->p_sys->hwnd )
UpdateRects( p_vout, VLC_TRUE );
break;
#if 0
case WM_ACTIVATE:
msg_Err( p_vout, "WM_ACTIVATE: %i", wParam );
if( wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE )
GXResume();
else if( wParam == WA_INACTIVE )
GXSuspend();
break;
#endif
case WM_KILLFOCUS:
p_vout->p_sys->b_focus = VLC_FALSE;
if( !p_vout->p_sys->b_parent_focus ) GXSuspend();
if( hWnd == p_vout->p_sys->hfswnd )
{
#ifdef UNDER_CE
HWND htbar = FindWindow( _T("HHTaskbar"), NULL );
ShowWindow( htbar, SW_SHOW );
#endif
}
if( !p_vout->p_sys->hparent ||
hWnd == p_vout->p_sys->hfswnd )
{
SHFullScreen( hWnd, SHFS_SHOWSIPBUTTON );
}
break;
case WM_SETFOCUS:
p_vout->p_sys->b_focus = VLC_TRUE;
GXResume();
if( p_vout->p_sys->hparent &&
hWnd != p_vout->p_sys->hfswnd && p_vout->b_fullscreen )
p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
if( hWnd == p_vout->p_sys->hfswnd )
{
#ifdef UNDER_CE
HWND htbar = FindWindow( _T("HHTaskbar"), NULL );
ShowWindow( htbar, SW_HIDE );
#endif
}
if( !p_vout->p_sys->hparent ||
hWnd == p_vout->p_sys->hfswnd )
{
SHFullScreen( hWnd, SHFS_HIDESIPBUTTON );
}
break;
case WM_LBUTTONDOWN:
p_vout->p_sys->i_changes |= VOUT_FULLSCREEN_CHANGE;
break;
case WM_MOUSEMOVE:
break;
case WM_LBUTTONUP:
break;
case WM_INITMENUPOPUP:
p_vout->p_sys->b_video_display = VLC_FALSE;
break;
case WM_NOTIFY:
// Redo the video display because menu can be closed
// FIXME verify if p_child_window exits
if( (((NMHDR *)lParam)->code) == NM_CUSTOMDRAW )
p_vout->p_sys->b_video_display = VLC_TRUE;
break;
/* the user wants to close the window */
case WM_CLOSE:
{
playlist_t * p_playlist =
(playlist_t *)vlc_object_find( p_vout, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE );
if( p_playlist == NULL ) return 0;
playlist_Stop( p_playlist );
vlc_object_release( p_playlist );
return 0;
}
case WM_DESTROY:
msg_Dbg( p_vout, "WinProc WM_DESTROY" );
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -1274,89 +913,7 @@ static void InitBuffers( vout_thread_t *p_vout ) ...@@ -1274,89 +913,7 @@ static void InitBuffers( vout_thread_t *p_vout )
p_vout->p_sys->off_dc = CreateCompatibleDC( window_dc ); p_vout->p_sys->off_dc = CreateCompatibleDC( window_dc );
SelectObject( p_vout->p_sys->off_dc, p_vout->p_sys->off_bitmap ); SelectObject( p_vout->p_sys->off_dc, p_vout->p_sys->off_bitmap );
ReleaseDC( 0, window_dc ); ReleaseDC( p_vout->p_sys->hvideownd, window_dc );
#endif #endif
} }
/*****************************************************************************
* Control: control facility for the vout
*****************************************************************************/
static int Control( vout_thread_t *p_vout, int i_query, va_list args )
{
unsigned int *pi_width, *pi_height;
vlc_bool_t b_bool;
RECT rect_window;
POINT point;
switch( i_query )
{
case VOUT_GET_SIZE:
if( p_vout->p_sys->hparent )
return vout_ControlWindow( p_vout,
(void *)p_vout->p_sys->hparent, i_query, args );
pi_width = va_arg( args, unsigned int * );
pi_height = va_arg( args, unsigned int * );
GetClientRect( p_vout->p_sys->hwnd, &rect_window );
*pi_width = rect_window.right - rect_window.left;
*pi_height = rect_window.bottom - rect_window.top;
return VLC_SUCCESS;
case VOUT_SET_SIZE:
if( p_vout->p_sys->hparent )
return vout_ControlWindow( p_vout,
(void *)p_vout->p_sys->hparent, i_query, args );
/* Update dimensions */
rect_window.top = rect_window.left = 0;
rect_window.right = va_arg( args, unsigned int );
rect_window.bottom = va_arg( args, unsigned int );
if( !rect_window.right ) rect_window.right = p_vout->i_window_width;
if( !rect_window.bottom ) rect_window.bottom = p_vout->i_window_height;
AdjustWindowRect( &rect_window, p_vout->p_sys->i_window_style, 0 );
SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
rect_window.right - rect_window.left,
rect_window.bottom - rect_window.top, SWP_NOMOVE );
return VLC_SUCCESS;
case VOUT_CLOSE:
ShowWindow( p_vout->p_sys->hwnd, SW_HIDE );
case VOUT_REPARENT:
/* Change window style, borders and title bar */
//vlc_mutex_lock( &p_vout->p_sys->lock );
p_vout->p_sys->hparent = 0;
//vlc_mutex_unlock( &p_vout->p_sys->lock );
/* Retrieve the window position */
point.x = point.y = 0;
ClientToScreen( p_vout->p_sys->hwnd, &point );
SetParent( p_vout->p_sys->hwnd, 0 );
p_vout->p_sys->i_window_style =
WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW | WS_SIZEBOX;
SetWindowLong( p_vout->p_sys->hwnd, GWL_STYLE,
p_vout->p_sys->i_window_style |
(i_query == VOUT_CLOSE ? 0 : WS_VISIBLE) );
SetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW );
SetWindowPos( p_vout->p_sys->hwnd, 0, point.x, point.y, 0, 0,
SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED );
return vout_vaControlDefault( p_vout, i_query, args );
case VOUT_SET_FOCUS:
b_bool = va_arg( args, vlc_bool_t );
p_vout->p_sys->b_parent_focus = b_bool;
if( b_bool ) GXResume();
else if( !p_vout->p_sys->b_focus ) GXSuspend();
return VLC_SUCCESS;
default:
return vout_vaControlDefault( p_vout, i_query, args );
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment