Commit eb12915b authored by Adrien Maglo's avatar Adrien Maglo Committed by Jean-Baptiste Kempf

Add a desktop mode to the Direct3d video output. This allow displaying video...

Add a desktop mode to the Direct3d video output. This allow displaying video on a window located just up the desktop icon window.
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent f52524a2
......@@ -220,6 +220,7 @@ static int VideoAutoMenuBuilder( vout_thread_t *p_object,
PUSH_VAR( "video-on-top" );
#ifdef WIN32
PUSH_VAR( "directx-wallpaper" );
PUSH_VAR( "direct3d-desktop" );
#endif
PUSH_VAR( "video-snapshot" );
PUSH_VAR( "zoom" );
......@@ -558,6 +559,7 @@ QMenu *QVLCMenu::VideoMenu( intf_thread_t *p_intf, QMenu *current )
ACT_ADDCHECK( current, "video-on-top", qtr( "Always &On Top" ) );
#ifdef WIN32
ACT_ADDCHECK( current, "directx-wallpaper", qtr( "DirectX Wallpaper" ) );
ACT_ADDCHECK( current, "direct3d-desktop", qtr( "Direct3D Desktop mode" ) );
#endif
ACT_ADD( current, "video-snapshot", qtr( "Sna&pshot" ) );
......
......@@ -80,6 +80,10 @@ static int Direct3DVoutCreateScene ( vout_thread_t * );
static void Direct3DVoutReleaseScene ( vout_thread_t * );
static void Direct3DVoutRenderScene ( vout_thread_t *, picture_t * );
static int DesktopCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void *p_data );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
......@@ -111,10 +115,18 @@ static int OpenVideoVista( vlc_object_t *obj )
return IsVistaOrAbove() ? OpenVideo( obj ) : VLC_EGENERIC;
}
#define DESKTOP_TEXT N_("Enable desktop mode ")
#define DESKTOP_LONGTEXT N_( \
"The desktop mode allows you to display the video on the desktop." )
vlc_module_begin ()
set_shortname( "Direct3D" )
set_category( CAT_VIDEO )
set_subcategory( SUBCAT_VIDEO_VOUT )
add_bool( "direct3d-desktop", 0, NULL, DESKTOP_TEXT, DESKTOP_LONGTEXT,
true )
set_description( N_("DirectX 3D video output") )
set_capability( "video output", 50 )
add_shortcut( "direct3d" )
......@@ -158,6 +170,7 @@ typedef struct
*****************************************************************************/
static int OpenVideo( vlc_object_t *p_this )
{
vlc_value_t val;
vout_thread_t * p_vout = (vout_thread_t *)p_this;
/* Allocate structure */
......@@ -183,6 +196,7 @@ static int OpenVideo( vlc_object_t *p_this )
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->b_desktop = false;
vlc_mutex_init( &p_vout->p_sys->lock );
SetRectEmpty( &p_vout->p_sys->rect_display );
SetRectEmpty( &p_vout->p_sys->rect_parent );
......@@ -208,6 +222,13 @@ static int OpenVideo( vlc_object_t *p_this )
/* Trigger a callback right now */
var_TriggerCallback( p_vout, "video-on-top" );
/* Trigger a callback right now */
var_Create( p_vout, "direct3d-desktop", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
val.psz_string = _("Desktop");
var_Change( p_vout, "direct3d-desktop", VLC_VAR_SETTEXT, &val, NULL );
var_AddCallback( p_vout, "direct3d-desktop", DesktopCallback, NULL );
var_TriggerCallback( p_vout, "direct3d-desktop" );
DisableScreensaver ( p_vout );
return VLC_SUCCESS;
......@@ -332,6 +353,7 @@ static int Manage( vout_thread_t *p_vout )
rect_parent.right - rect_parent.left,
rect_parent.bottom - rect_parent.top,
SWP_NOZORDER );
UpdateRects( p_vout, true );
}
}
else
......@@ -363,6 +385,35 @@ static int Manage( vout_thread_t *p_vout )
#endif
p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;
}
/*
* Desktop mode change
*/
if( p_vout->p_sys->i_changes & DX_DESKTOP_CHANGE )
{
/* Close the direct3d instance attached to the current output window. */
End( p_vout );
StopEventThread( p_vout );
/* Set the switching mode flag */
p_vout->p_sys->i_changes |= SWITCHING_MODE_FLAG;
/* Reset the flag */
p_vout->p_sys->i_changes &= ~DX_DESKTOP_CHANGE;
}
if( p_vout->p_sys->i_changes & EVENT_THREAD_ENDED
&& p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
{
/* Open the direct3d output and attaches it to the new window */
p_vout->p_sys->b_desktop = !p_vout->p_sys->b_desktop;
p_vout->pf_display = FirstDisplay;
CreateEventThread( p_vout );
Init( p_vout );
/* Reset the flags */
p_vout->p_sys->i_changes &= ~EVENT_THREAD_ENDED;
p_vout->p_sys->i_changes &= ~SWITCHING_MODE_FLAG;
}
/* autoscale toggle */
if( p_vout->i_changes & VOUT_SCALE_CHANGE )
......@@ -493,6 +544,10 @@ static int Manage( vout_thread_t *p_vout )
static void Display( vout_thread_t *p_vout, picture_t *p_pic )
{
LPDIRECT3DDEVICE9 p_d3ddev = p_vout->p_sys->p_d3ddev;
if( p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
return;
// Present the back buffer contents to the display
// stretching and filtering happens here
HRESULT hr = IDirect3DDevice9_Present(p_d3ddev,
......@@ -1266,6 +1321,9 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
HRESULT hr;
float f_width, f_height;
if( p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
return;
// check if device is still available
hr = IDirect3DDevice9_TestCooperativeLevel(p_d3ddev);
if( FAILED(hr) )
......@@ -1423,3 +1481,36 @@ static void Direct3DVoutRenderScene( vout_thread_t *p_vout, picture_t *p_pic )
}
}
/*****************************************************************************
* DesktopCallback: desktop mode variable callback
*****************************************************************************/
static int DesktopCallback( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void *p_data )
{
VLC_UNUSED( psz_cmd );
VLC_UNUSED( oldval );
VLC_UNUSED( p_data );
vout_thread_t *p_vout = (vout_thread_t *)p_this;
if( (newval.b_bool && !p_vout->p_sys->b_desktop) ||
(!newval.b_bool && p_vout->p_sys->b_desktop) )
{
playlist_t *p_playlist = pl_Hold( p_vout );
if( p_playlist )
{
/* Modify playlist as well because the vout might have to be
* restarted */
var_Create( p_playlist, "direct3d-desktop", VLC_VAR_BOOL );
var_Set( p_playlist, "direct3d-desktop", newval );
pl_Release( p_vout );
}
p_vout->p_sys->i_changes |= DX_DESKTOP_CHANGE;
}
return VLC_SUCCESS;
}
......@@ -383,11 +383,11 @@ void* EventThread( vlc_object_t *p_this )
msg_Dbg( p_event, "DirectXEventThread terminating" );
/* clear the changes formerly signaled */
p_event->p_vout->p_sys->i_changes = 0;
DirectXCloseWindow( p_event->p_vout );
vlc_restorecancel (canc);
/* clear the changes formerly signaled */
p_event->p_vout->p_sys->i_changes = EVENT_THREAD_ENDED;
return NULL;
}
......@@ -416,14 +416,31 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
/* Get this module's instance */
hInstance = GetModuleHandle(NULL);
/* If an external window was specified, we'll draw in it. */
p_vout->p_sys->parent_window =
vout_RequestHWND( p_vout, &p_vout->p_sys->i_window_x,
#ifdef MODULE_NAME_IS_direct3d
if( !p_vout->p_sys->b_desktop )
{
#endif
/* If an external window was specified, we'll draw in it. */
p_vout->p_sys->parent_window =
vout_RequestHWND( p_vout, &p_vout->p_sys->i_window_x,
&p_vout->p_sys->i_window_y,
&p_vout->p_sys->i_window_width,
&p_vout->p_sys->i_window_height );
if( p_vout->p_sys->parent_window )
p_vout->p_sys->hparent = p_vout->p_sys->parent_window->handle.hwnd;
if( p_vout->p_sys->parent_window )
p_vout->p_sys->hparent = p_vout->p_sys->parent_window->handle.hwnd;
#ifdef MODULE_NAME_IS_direct3d
}
else
{
/* Find Program Manager */
HWND hwnd = FindWindow( _T("Progman"), NULL );
if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SHELLDLL_DefView"), NULL );
if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SysListView32"), NULL );
if( !hwnd )
msg_Err( p_vout, "Couldn't find desktop icon window. Desktop mode can't be established." );
p_vout->p_sys->hparent = hwnd;
}
#endif
/* We create the window ourself, there is no previous window proc. */
p_vout->p_sys->pf_wndproc = NULL;
......@@ -601,7 +618,10 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
DestroyWindow( p_vout->p_sys->hwnd );
if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd );
vout_ReleaseWindow( p_vout->p_sys->parent_window );
#ifdef MODULE_NAME_IS_direct3d
if( !p_vout->p_sys->b_desktop )
#endif
vout_ReleaseWindow( p_vout->p_sys->parent_window );
p_vout->p_sys->hwnd = NULL;
/* We don't unregister the Window Class because it could lead to race
......@@ -1322,5 +1342,6 @@ void StopEventThread( vout_thread_t *p_vout )
vlc_object_release( p_vout->p_sys->p_event );
}
vlc_mutex_destroy( &p_vout->p_sys->lock );
if( !p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG )
vlc_mutex_destroy( &p_vout->p_sys->lock );
}
......@@ -168,6 +168,9 @@ struct vout_sys_t
#endif
#ifdef MODULE_NAME_IS_direct3d
/* show video on desktop window ? */
bool b_desktop;
// core objects
HINSTANCE hd3d9_dll; /* handle of the opened d3d9 dll */
LPDIRECT3D9 p_d3dobj;
......@@ -270,6 +273,9 @@ void StopEventThread ( vout_thread_t *p_vout );
#define IDM_TOGGLE_ON_TOP WM_USER + 1
#define DX_POSITION_CHANGE 0x1000
#define DX_WALLPAPER_CHANGE 0x2000
#define DX_DESKTOP_CHANGE 0x4000
#define EVENT_THREAD_ENDED 0x6000
#define SWITCHING_MODE_FLAG 0x8000
/*****************************************************************************
* WinCE helpers
......
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