Commit 92be1f61 authored by Gildas Bazin's avatar Gildas Bazin

* modules/video_output/directx/*:

  - Major changes to way the embedded vout is handled.
    + the vout windows are created in our event thread so we do receive the events now.
    + we do not use the external window directly (as for normal vout we create our vout window + video sub-window).
    + Create a WS_EX_NOPARENTNOTIFY vout window to make mozilla happy.
  - Improved the mouse auto-hide feature.
  - Do the DirectXUpdateOverlay() in the events thread. This should make S3 graphics cards happy again.
parent 10a593e4
...@@ -160,7 +160,7 @@ vlc_module_end(); ...@@ -160,7 +160,7 @@ vlc_module_end();
static int OpenVideo( vlc_object_t *p_this ) static int OpenVideo( 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;
vlc_value_t val, text; vlc_value_t val;
HMODULE huser32; HMODULE huser32;
/* Allocate structure */ /* Allocate structure */
...@@ -186,7 +186,9 @@ static int OpenVideo( vlc_object_t *p_this ) ...@@ -186,7 +186,9 @@ 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 = NULL; p_vout->p_sys->hparent = NULL;
p_vout->p_sys->i_changes = 0; p_vout->p_sys->i_changes = 0;
SetRectEmpty( &p_vout->p_sys->rect_display ); vlc_mutex_init( p_vout, &p_vout->p_sys->lock );
SetRectEmpty( &p_vout->p_sys->rect_display );
SetRectEmpty( &p_vout->p_sys->rect_parent );
/* Multimonitor stuff */ /* Multimonitor stuff */
p_vout->p_sys->hmonitor = NULL; p_vout->p_sys->hmonitor = NULL;
...@@ -371,8 +373,7 @@ static int Init( vout_thread_t *p_vout ) ...@@ -371,8 +373,7 @@ static int Init( vout_thread_t *p_vout )
} }
/* Change the window title bar text */ /* Change the window title bar text */
if( p_vout->p_sys->hparent ) ; /* Do nothing */ PostMessage( p_vout->p_sys->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
else PostMessage( p_vout->p_sys->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -422,6 +423,8 @@ static void CloseVideo( vlc_object_t *p_this ) ...@@ -422,6 +423,8 @@ static void CloseVideo( vlc_object_t *p_this )
vlc_object_destroy( p_vout->p_sys->p_event ); vlc_object_destroy( p_vout->p_sys->p_event );
} }
vlc_mutex_destroy( &p_vout->p_sys->lock );
if( p_vout->p_sys ) if( p_vout->p_sys )
{ {
free( p_vout->p_sys ); free( p_vout->p_sys );
...@@ -441,9 +444,37 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -441,9 +444,37 @@ static int Manage( vout_thread_t *p_vout )
/* 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 ) if( p_vout->p_sys->hparent )
{ {
DirectXUpdateRects( p_vout, VLC_FALSE ); RECT rect_parent;
POINT point;
vlc_mutex_unlock( &p_vout->p_sys->lock );
GetClientRect( p_vout->p_sys->hparent, &rect_parent );
point.x = point.y = 0;
ClientToScreen( p_vout->p_sys->hparent, &point );
OffsetRect( &rect_parent, point.x, point.y );
if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )
{
p_vout->p_sys->rect_parent = rect_parent;
/* This one is to force the update even if only
* the position has changed */
SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1,
rect_parent.right - rect_parent.left,
rect_parent.bottom - rect_parent.top, 0 );
SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
rect_parent.right - rect_parent.left,
rect_parent.bottom - rect_parent.top, 0 );
}
}
else
{
vlc_mutex_unlock( &p_vout->p_sys->lock );
} }
/* /*
...@@ -453,9 +484,6 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -453,9 +484,6 @@ static int Manage( vout_thread_t *p_vout )
{ {
p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE; p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;
if( p_vout->p_sys->b_using_overlay )
DirectXUpdateOverlay( p_vout );
/* Check if we are still on the same monitor */ /* Check if we are still on the same monitor */
if( p_vout->p_sys->MonitorFromWindow && if( p_vout->p_sys->MonitorFromWindow &&
p_vout->p_sys->hmonitor != p_vout->p_sys->hmonitor !=
...@@ -478,6 +506,7 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -478,6 +506,7 @@ 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;
vlc_value_t val; vlc_value_t val;
p_vout->b_fullscreen = ! p_vout->b_fullscreen; p_vout->b_fullscreen = ! p_vout->b_fullscreen;
...@@ -487,21 +516,33 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -487,21 +516,33 @@ static int Manage( vout_thread_t *p_vout )
GetWindowPlacement( p_vout->p_sys->hwnd, &window_placement ); GetWindowPlacement( p_vout->p_sys->hwnd, &window_placement );
if( p_vout->b_fullscreen ) if( p_vout->b_fullscreen )
{ {
if( p_vout->p_sys->hparent )
SetParent( p_vout->p_sys->hwnd, GetDesktopWindow() );
/* Maximized window */ /* Maximized window */
window_placement.showCmd = SW_SHOWMAXIMIZED; window_placement.showCmd = SW_SHOWMAXIMIZED;
/* Change window style, no borders and no title bar */ /* Change window style, no borders and no title bar */
SetWindowLong( p_vout->p_sys->hwnd, GWL_STYLE, WS_CLIPCHILDREN ); i_style = WS_CLIPCHILDREN;
} }
else else
{ {
if( p_vout->p_sys->hparent )
{
SetParent( p_vout->p_sys->hwnd, p_vout->p_sys->hparent );
i_style = WS_CLIPCHILDREN | WS_VISIBLE | WS_CHILD;
}
else
{
i_style = WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW |
WS_SIZEBOX | WS_VISIBLE;
}
/* Normal window */ /* Normal window */
window_placement.showCmd = SW_SHOWNORMAL; window_placement.showCmd = SW_SHOWNORMAL;
/* Change window style, borders and title bar */
SetWindowLong( p_vout->p_sys->hwnd, GWL_STYLE, WS_CLIPCHILDREN |
WS_OVERLAPPEDWINDOW | WS_SIZEBOX | WS_VISIBLE );
} }
/* Change window style, borders and title bar */
SetWindowLong( p_vout->p_sys->hwnd, GWL_STYLE, i_style );
SetWindowPlacement( p_vout->p_sys->hwnd, &window_placement ); SetWindowPlacement( p_vout->p_sys->hwnd, &window_placement );
/* Update the object variable and trigger callback */ /* Update the object variable and trigger callback */
...@@ -518,12 +559,24 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -518,12 +559,24 @@ static int Manage( vout_thread_t *p_vout )
if( (!p_vout->p_sys->b_cursor_hidden) && if( (!p_vout->p_sys->b_cursor_hidden) &&
( (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 ) ) ( (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 ) )
{ {
/* Hide the mouse automatically */ POINT point;
if( p_vout->p_sys->hwnd != p_vout->p_sys->hparent ) RECT rect;
/* Hide the cursor only if it is inside our window */
GetClientRect( p_vout->p_sys->hwnd, &rect );
point.x = point.y = 0;
ClientToScreen( p_vout->p_sys->hwnd, &point );
OffsetRect( &rect, point.x, point.y );
GetCursorPos( &point );
if( PtInRect( &rect, point ) )
{ {
p_vout->p_sys->b_cursor_hidden = VLC_TRUE; p_vout->p_sys->b_cursor_hidden = VLC_TRUE;
PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 ); PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
} }
else
{
p_vout->p_sys->i_lastmoved = mdate();
}
} }
/* /*
...@@ -1084,9 +1137,14 @@ int DirectXUpdateOverlay( vout_thread_t *p_vout ) ...@@ -1084,9 +1137,14 @@ int DirectXUpdateOverlay( vout_thread_t *p_vout )
RECT rect_src = p_vout->p_sys->rect_src_clipped; RECT rect_src = p_vout->p_sys->rect_src_clipped;
RECT rect_dest = p_vout->p_sys->rect_dest_clipped; RECT rect_dest = p_vout->p_sys->rect_dest_clipped;
if( p_vout->p_sys->p_current_surface == NULL || if( !p_vout->p_sys->b_using_overlay ) return VLC_EGENERIC;
!p_vout->p_sys->b_using_overlay )
vlc_mutex_lock( &p_vout->p_sys->lock );
if( p_vout->p_sys->p_current_surface == NULL )
{
vlc_mutex_unlock( &p_vout->p_sys->lock );
return VLC_EGENERIC; return VLC_EGENERIC;
}
/* The new window dimensions should already have been computed by the /* The new window dimensions should already have been computed by the
* caller of this function */ * caller of this function */
...@@ -1103,6 +1161,9 @@ int DirectXUpdateOverlay( vout_thread_t *p_vout ) ...@@ -1103,6 +1161,9 @@ int DirectXUpdateOverlay( vout_thread_t *p_vout )
p_vout->p_sys->p_current_surface, p_vout->p_sys->p_current_surface,
&rect_src, p_vout->p_sys->p_display, &rect_dest, &rect_src, p_vout->p_sys->p_display, &rect_dest,
dwFlags, &ddofx ); dwFlags, &ddofx );
vlc_mutex_unlock( &p_vout->p_sys->lock );
if(dxresult != DD_OK) if(dxresult != DD_OK)
{ {
msg_Warn( p_vout, "DirectXUpdateOverlay cannot move/resize overlay" ); msg_Warn( p_vout, "DirectXUpdateOverlay cannot move/resize overlay" );
...@@ -1435,6 +1496,10 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1435,6 +1496,10 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic,
{ {
int i; int i;
vlc_mutex_lock( &p_vout->p_sys->lock );
p_vout->p_sys->p_current_surface = 0;
vlc_mutex_unlock( &p_vout->p_sys->lock );
for( i = 0; i < i_num_pics; i++ ) for( i = 0; i < i_num_pics; i++ )
{ {
DirectXCloseSurface( p_vout, p_pic[i].p_sys->p_front_surface ); DirectXCloseSurface( p_vout, p_pic[i].p_sys->p_front_surface );
...@@ -1444,8 +1509,6 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic, ...@@ -1444,8 +1509,6 @@ static void FreePictureVec( vout_thread_t *p_vout, picture_t *p_pic,
free( p_pic[i].p_sys ); free( p_pic[i].p_sys );
} }
} }
p_vout->p_sys->p_current_surface = 0;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -81,7 +81,7 @@ static int DirectXConvertKey( int i_key ); ...@@ -81,7 +81,7 @@ static int DirectXConvertKey( int i_key );
void DirectXEventThread( event_thread_t *p_event ) void DirectXEventThread( event_thread_t *p_event )
{ {
MSG msg; MSG msg;
POINT old_mouse_pos = {0,0}; POINT old_mouse_pos = {0,0}, mouse_pos;
vlc_value_t val; vlc_value_t val;
int i_width, i_height, i_x, i_y; int i_width, i_height, i_x, i_y;
HMODULE hkernel32; HMODULE hkernel32;
...@@ -118,21 +118,13 @@ void DirectXEventThread( event_thread_t *p_event ) ...@@ -118,21 +118,13 @@ void DirectXEventThread( event_thread_t *p_event )
/* 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 */
while( !p_event->b_die && ( p_event->p_vout->p_sys->hparent || while( !p_event->b_die &&
GetMessage( &msg, p_event->p_vout->p_sys->hwnd, 0, 0 ) ) ) GetMessage( &msg, p_event->p_vout->p_sys->hwnd, 0, 0 ) )
{ {
/* Check if we are asked to exit */ /* Check if we are asked to exit */
if( p_event->b_die ) if( p_event->b_die )
break; break;
if( p_event->p_vout->p_sys->hparent )
{
/* Parent window was created in another thread so we can't
* access the window messages. */
msleep( INTF_IDLE_SLEEP );
continue;
}
switch( msg.message ) switch( msg.message )
{ {
...@@ -162,8 +154,9 @@ void DirectXEventThread( event_thread_t *p_event ) ...@@ -162,8 +154,9 @@ void DirectXEventThread( event_thread_t *p_event )
} }
case WM_NCMOUSEMOVE: case WM_NCMOUSEMOVE:
if( (abs(GET_X_LPARAM(msg.lParam) - old_mouse_pos.x) > 2 || GetCursorPos( &mouse_pos );
(abs(GET_Y_LPARAM(msg.lParam) - old_mouse_pos.y)) > 2 ) ) if( (abs(mouse_pos.x - old_mouse_pos.x) > 2 ||
(abs(mouse_pos.y - old_mouse_pos.y)) > 2 ) )
{ {
GetCursorPos( &old_mouse_pos ); GetCursorPos( &old_mouse_pos );
p_event->p_vout->p_sys->i_lastmoved = mdate(); p_event->p_vout->p_sys->i_lastmoved = mdate();
...@@ -348,6 +341,10 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -348,6 +341,10 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
HINSTANCE hInstance; HINSTANCE hInstance;
HMENU hMenu; HMENU hMenu;
RECT rect_window; RECT rect_window;
WNDCLASSEX wc; /* window class components */
HICON vlc_icon = NULL;
char vlc_path[MAX_PATH+1];
int i_style;
msg_Dbg( p_vout, "DirectXCreateWindow" ); msg_Dbg( p_vout, "DirectXCreateWindow" );
...@@ -355,116 +352,99 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -355,116 +352,99 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
hInstance = GetModuleHandle(NULL); hInstance = GetModuleHandle(NULL);
/* If an external window was specified, we'll draw in it. */ /* If an external window was specified, we'll draw in it. */
p_vout->p_sys->hparent = p_vout->p_sys->hwnd = p_vout->p_sys->hparent =
vout_RequestWindow( p_vout, &p_vout->p_sys->i_window_x, vout_RequestWindow( p_vout, &p_vout->p_sys->i_window_x,
&p_vout->p_sys->i_window_y, &p_vout->p_sys->i_window_y,
&p_vout->p_sys->i_window_width, &p_vout->p_sys->i_window_width,
&p_vout->p_sys->i_window_height ); &p_vout->p_sys->i_window_height );
if( p_vout->p_sys->hparent ) /* We create the window ourself, there is no previous window proc. */
p_vout->p_sys->pf_wndproc = NULL;
/* Get the Icon from the main app */
vlc_icon = NULL;
if( GetModuleFileName( NULL, vlc_path, MAX_PATH ) )
{ {
msg_Dbg( p_vout, "using external window %p\n", p_vout->p_sys->hwnd ); vlc_icon = ExtractIcon( hInstance, vlc_path, 0 );
/* Set stuff in the window that we can not put directly in
* a class (see below). */
SetClassLong( p_vout->p_sys->hwnd,
GCL_STYLE, CS_DBLCLKS );
SetClassLong( p_vout->p_sys->hwnd,
GCL_HBRBACKGROUND, (LONG)GetStockObject(BLACK_BRUSH) );
SetClassLong( p_vout->p_sys->hwnd,
GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW) );
/* Store a p_vout pointer into the window local storage (for later
* use in DirectXEventProc). */
SetWindowLongPtr( p_vout->p_sys->hwnd, GWLP_USERDATA, (LONG_PTR)p_vout );
p_vout->p_sys->pf_wndproc =
(WNDPROC)SetWindowLong( p_vout->p_sys->hwnd, GWLP_WNDPROC,
(LONG_PTR)DirectXEventProc );
/* Blam! Erase everything that might have been there. */
InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
} }
else
/* Fill in the window class structure */
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS; /* style: dbl click */
wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */
wc.cbClsExtra = 0; /* no extra class data */
wc.cbWndExtra = 0; /* no extra window data */
wc.hInstance = hInstance; /* instance */
wc.hIcon = vlc_icon; /* load the vlc big icon */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* default cursor */
wc.hbrBackground = GetStockObject(BLACK_BRUSH); /* background color */
wc.lpszMenuName = NULL; /* no menu */
wc.lpszClassName = "VLC DirectX"; /* use a special class */
wc.hIconSm = vlc_icon; /* load the vlc small icon */
/* Register the window class */
if( !RegisterClassEx(&wc) )
{ {
WNDCLASSEX wc; /* window class components */ WNDCLASS wndclass;
HICON vlc_icon = NULL;
char vlc_path[MAX_PATH+1];
/* We create the window ourself, there is no previous window proc. */ if( vlc_icon ) DestroyIcon( vlc_icon );
p_vout->p_sys->pf_wndproc = NULL;
/* Get the Icon from the main app */ /* Check why it failed. If it's because one already exists
vlc_icon = NULL; * then fine, otherwise return with an error. */
if( GetModuleFileName( NULL, vlc_path, MAX_PATH ) ) if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
{ {
vlc_icon = ExtractIcon( hInstance, vlc_path, 0 ); msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
return VLC_EGENERIC;
} }
}
/* Fill in the window class structure */ /* When you create a window you give the dimensions you wish it to
wc.cbSize = sizeof(WNDCLASSEX); * have. Unfortunatly these dimensions will include the borders and
wc.style = CS_DBLCLKS; /* style: dbl click */ * titlebar. We use the following function to find out the size of
wc.lpfnWndProc = (WNDPROC)DirectXEventProc; /* event handler */ * the window corresponding to the useable surface we want */
wc.cbClsExtra = 0; /* no extra class data */ rect_window.top = 10;
wc.cbWndExtra = 0; /* no extra window data */ rect_window.left = 10;
wc.hInstance = hInstance; /* instance */ rect_window.right = rect_window.left + p_vout->p_sys->i_window_width;
wc.hIcon = vlc_icon; /* load the vlc big icon */ rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* default cursor */ AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
wc.hbrBackground = GetStockObject(BLACK_BRUSH); /* background color */
wc.lpszMenuName = NULL; /* no menu */
wc.lpszClassName = "VLC DirectX"; /* use a special class */
wc.hIconSm = vlc_icon; /* load the vlc small icon */
/* Register the window class */
if( !RegisterClassEx(&wc) )
{
WNDCLASS wndclass;
if( vlc_icon ) if( p_vout->p_sys->hparent )
{ i_style = WS_VISIBLE|WS_CLIPCHILDREN|WS_CHILD;
DestroyIcon( vlc_icon ); else
} i_style = WS_OVERLAPPEDWINDOW|WS_SIZEBOX|WS_VISIBLE|WS_CLIPCHILDREN;
/* Check why it failed. If it's because one already exists
* then fine, otherwise return with an error. */
if( !GetClassInfo( hInstance, "VLC DirectX", &wndclass ) )
{
msg_Err( p_vout, "DirectXCreateWindow RegisterClass FAILED" );
return VLC_EGENERIC;
}
}
/* When you create a window you give the dimensions you wish it to
* have. Unfortunatly these dimensions will include the borders and
* titlebar. We use the following function to find out the size of
* the window corresponding to the useable surface we want */
rect_window.top = 10;
rect_window.left = 10;
rect_window.right = rect_window.left + p_vout->p_sys->i_window_width;
rect_window.bottom = rect_window.top + p_vout->p_sys->i_window_height;
AdjustWindowRect( &rect_window, WS_OVERLAPPEDWINDOW|WS_SIZEBOX, 0 );
/* Create the window */ /* Create the window */
p_vout->p_sys->hwnd = p_vout->p_sys->hwnd =
CreateWindow( "VLC DirectX", /* name of window class */ CreateWindowEx( WS_EX_NOPARENTNOTIFY,
"VLC DirectX", /* name of window class */
VOUT_TITLE " (DirectX Output)", /* window title bar text */ VOUT_TITLE " (DirectX Output)", /* window title bar text */
WS_OVERLAPPEDWINDOW | WS_SIZEBOX | WS_VISIBLE | i_style, /* window style */
WS_CLIPCHILDREN, /* window style */
(p_vout->p_sys->i_window_x < 0) ? CW_USEDEFAULT : (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_x, /* default X coordinate */
(p_vout->p_sys->i_window_y < 0) ? CW_USEDEFAULT : (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_y, /* default Y coordinate */
rect_window.right - rect_window.left, /* window width */ rect_window.right - rect_window.left, /* window width */
rect_window.bottom - rect_window.top, /* window height */ rect_window.bottom - rect_window.top, /* window height */
NULL, /* no parent window */ p_vout->p_sys->hparent, /* parent window */
NULL, /* no menu in this window */ NULL, /* no menu in this window */
hInstance, /* handle of this program instance */ hInstance, /* handle of this program instance */
(LPVOID)p_vout ); /* send p_vout to WM_CREATE */ (LPVOID)p_vout ); /* send p_vout to WM_CREATE */
if( !p_vout->p_sys->hwnd ) if( !p_vout->p_sys->hwnd )
{ {
msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" ); msg_Warn( p_vout, "DirectXCreateWindow create window FAILED" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( p_vout->p_sys->hparent )
{
LONG i_style;
/* We don't want the window owner to overwrite our client area */
i_style = GetWindowLong( p_vout->p_sys->hparent, GWL_STYLE );
SetWindowLong( p_vout->p_sys->hparent, GWL_STYLE,
i_style | WS_CLIPCHILDREN );
} }
/* Now display the window */ /* Now display the window */
...@@ -493,25 +473,10 @@ static void DirectXCloseWindow( vout_thread_t *p_vout ) ...@@ -493,25 +473,10 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
{ {
msg_Dbg( p_vout, "DirectXCloseWindow" ); msg_Dbg( p_vout, "DirectXCloseWindow" );
if( p_vout->p_sys->hwnd && !p_vout->p_sys->hparent ) DestroyWindow( p_vout->p_sys->hwnd );
{
DestroyWindow( p_vout->p_sys->hwnd );
}
else if( p_vout->p_sys->hparent )
{
/* Get rid of the video sub-window */
PostMessage( p_vout->p_sys->hvideownd, WM_VLC_DESTROY_VIDEO_WIN, 0, 0);
/* We don't want our windowproc to be called anymore */
SetWindowLongPtr( p_vout->p_sys->hwnd,
GWLP_WNDPROC, (LONG_PTR)p_vout->p_sys->pf_wndproc );
SetWindowLongPtr( p_vout->p_sys->hwnd, GWLP_USERDATA, 0 );
/* Blam! Erase everything that might have been there. */
InvalidateRect( p_vout->p_sys->hwnd, NULL, TRUE );
if( p_vout->p_sys->hparent )
vout_ReleaseWindow( p_vout, (void *)p_vout->p_sys->hparent ); vout_ReleaseWindow( p_vout, (void *)p_vout->p_sys->hparent );
}
p_vout->p_sys->hwnd = NULL; p_vout->p_sys->hwnd = NULL;
...@@ -662,6 +627,9 @@ void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force ) ...@@ -662,6 +627,9 @@ void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
rect_dest_clipped.top -= p_vout->p_sys->rect_display.top; rect_dest_clipped.top -= p_vout->p_sys->rect_display.top;
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 )
DirectXUpdateOverlay( p_vout );
/* Signal the change in size/position */ /* Signal the change in size/position */
p_vout->p_sys->i_changes |= DX_POSITION_CHANGE; p_vout->p_sys->i_changes |= DX_POSITION_CHANGE;
...@@ -799,31 +767,8 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -799,31 +767,8 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
break; break;
} }
if( p_vout->p_sys->pf_wndproc ) /* Let windows handle the message */
{ return DefWindowProc(hwnd, message, wParam, lParam);
LRESULT i_ret;
/* Hmmm mozilla does manage somehow to save the pointer to our
* windowproc and will call us again whereby creating an
* infinite loop.
* We can detect this by resetting GWL_USERDATA before calling
* the parent's windowproc. */
SetWindowLongPtr( p_vout->p_sys->hwnd, GWLP_USERDATA, 0 );
/* Call next window proc in chain */
i_ret = CallWindowProc( p_vout->p_sys->pf_wndproc, hwnd, message,
wParam, lParam );
SetWindowLongPtr( p_vout->p_sys->hwnd, GWLP_USERDATA,
(LONG_PTR)p_vout );
return i_ret;
}
else
{
/* Let windows handle the message */
return DefWindowProc(hwnd, message, wParam, lParam);
}
} }
static long FAR PASCAL DirectXVideoEventProc( HWND hwnd, UINT message, static long FAR PASCAL DirectXVideoEventProc( HWND hwnd, UINT message,
...@@ -834,10 +779,6 @@ static long FAR PASCAL DirectXVideoEventProc( HWND hwnd, UINT message, ...@@ -834,10 +779,6 @@ static long FAR PASCAL DirectXVideoEventProc( HWND hwnd, UINT message,
switch( message ) switch( message )
{ {
case WM_VLC_DESTROY_VIDEO_WIN:
/* Destroy video sub-window */
DestroyWindow( hwnd );
break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_LBUTTONUP: case WM_LBUTTONUP:
...@@ -961,6 +902,21 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args ) ...@@ -961,6 +902,21 @@ static int Control( vout_thread_t *p_vout, int i_query, va_list args )
return VLC_SUCCESS; return VLC_SUCCESS;
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 );
SetParent( p_vout->p_sys->hwnd, GetDesktopWindow() );
SetWindowLong( p_vout->p_sys->hwnd, GWL_STYLE,
WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW |
WS_SIZEBOX | WS_VISIBLE );
SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED );
return VLC_SUCCESS;
case VOUT_CLOSE: case VOUT_CLOSE:
return VLC_SUCCESS; return VLC_SUCCESS;
......
...@@ -77,6 +77,7 @@ struct vout_sys_t ...@@ -77,6 +77,7 @@ struct vout_sys_t
RECT rect_src_clipped; RECT rect_src_clipped;
RECT rect_dest; RECT rect_dest;
RECT rect_dest_clipped; RECT rect_dest_clipped;
RECT rect_parent;
/* Overlay alignment restrictions */ /* Overlay alignment restrictions */
int i_align_src_boundary; int i_align_src_boundary;
...@@ -97,9 +98,10 @@ struct vout_sys_t ...@@ -97,9 +98,10 @@ struct vout_sys_t
volatile mtime_t i_lastmoved; volatile mtime_t i_lastmoved;
/* Misc */ /* Misc */
vlc_bool_t b_on_top_change; vlc_bool_t b_on_top_change;
event_thread_t * p_event; event_thread_t *p_event;
vlc_mutex_t lock;
}; };
/***************************************************************************** /*****************************************************************************
......
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