Commit ff4158b4 authored by Gildas Bazin's avatar Gildas Bazin

* modules/video_output/directx/*: we now create a video sub-window which is a...

* modules/video_output/directx/*: we now create a video sub-window which is a child of the main window and which always fit exactly the size of the video.
  As a result the overlay color key is only painted in the video area and the rest of the window is pure black.
parent 9883237c
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* events.c: Windows DirectX video output events handler * events.c: Windows DirectX video output events handler
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: events.c,v 1.28 2003/10/31 18:18:46 gbazin Exp $ * $Id: events.c,v 1.29 2003/11/19 23:44:35 gbazin Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -263,7 +263,6 @@ void DirectXEventThread( event_thread_t *p_event ) ...@@ -263,7 +263,6 @@ void DirectXEventThread( event_thread_t *p_event )
static int DirectXCreateWindow( vout_thread_t *p_vout ) static int DirectXCreateWindow( vout_thread_t *p_vout )
{ {
HINSTANCE hInstance; HINSTANCE hInstance;
COLORREF colorkey;
HDC hdc; HDC hdc;
HMENU hMenu; HMENU hMenu;
RECT rect_window; RECT rect_window;
...@@ -275,33 +274,8 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -275,33 +274,8 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
/* Get this module's instance */ /* Get this module's instance */
hInstance = GetModuleHandle(NULL); hInstance = GetModuleHandle(NULL);
/* Create a BRUSH that will be used by Windows to paint the window
* background.
* This window background is important for us as it will be used by the
* graphics card to display the overlay.
* This is why we carefully choose the color for this background, the goal
* being to choose a color which isn't complete black but nearly. We
* obviously don't want to use black as a colorkey for the overlay because
* black is one of the most used color and thus would give us undesirable
* effects */
/* the first step is to find the colorkey we want to use. The difficulty
* comes from the potential dithering (depends on the display depth)
* because we need to know the real RGB value of the chosen colorkey */
hdc = GetDC( NULL );
for( colorkey = 0x0a; colorkey < 0xff /* all shades of red */; colorkey++ )
{
if( colorkey == GetNearestColor( hdc, colorkey ) )
{
break;
}
}
msg_Dbg( p_vout, "background color: %i", colorkey );
/* Create the actual brush */
p_vout->p_sys->hbrush = CreateSolidBrush(colorkey);
p_vout->p_sys->i_rgb_colorkey = (int)colorkey;
/* Get the current size of the display and its colour depth */ /* Get the current size of the display and its colour depth */
hdc = GetDC( NULL );
p_vout->p_sys->rect_display.right = GetDeviceCaps( hdc, HORZRES ); p_vout->p_sys->rect_display.right = GetDeviceCaps( hdc, HORZRES );
p_vout->p_sys->rect_display.bottom = GetDeviceCaps( hdc, VERTRES ); p_vout->p_sys->rect_display.bottom = GetDeviceCaps( hdc, VERTRES );
p_vout->p_sys->i_display_depth = GetDeviceCaps( hdc, BITSPIXEL ); p_vout->p_sys->i_display_depth = GetDeviceCaps( hdc, BITSPIXEL );
...@@ -309,7 +283,6 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -309,7 +283,6 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
p_vout->p_sys->rect_display.right, p_vout->p_sys->rect_display.right,
p_vout->p_sys->rect_display.bottom, p_vout->p_sys->rect_display.bottom,
p_vout->p_sys->i_display_depth ); p_vout->p_sys->i_display_depth );
ReleaseDC( NULL, hdc ); ReleaseDC( NULL, hdc );
/* If an external window was specified, we'll draw in it. */ /* If an external window was specified, we'll draw in it. */
...@@ -326,7 +299,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -326,7 +299,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
SetClassLong( p_vout->p_sys->hwnd, SetClassLong( p_vout->p_sys->hwnd,
GCL_STYLE, CS_DBLCLKS ); GCL_STYLE, CS_DBLCLKS );
SetClassLong( p_vout->p_sys->hwnd, SetClassLong( p_vout->p_sys->hwnd,
GCL_HBRBACKGROUND, (LONG)p_vout->p_sys->hbrush ); GCL_HBRBACKGROUND, (LONG)GetStockObject(BLACK_BRUSH) );
SetClassLong( p_vout->p_sys->hwnd, SetClassLong( p_vout->p_sys->hwnd,
GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW) ); GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_ARROW) );
/* Store a p_vout pointer into the window local storage (for later /* Store a p_vout pointer into the window local storage (for later
...@@ -363,7 +336,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -363,7 +336,7 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
wc.hInstance = hInstance; /* instance */ wc.hInstance = hInstance; /* instance */
wc.hIcon = vlc_icon; /* load the vlc big icon */ wc.hIcon = vlc_icon; /* load the vlc big icon */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* default cursor */ wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* default cursor */
wc.hbrBackground = p_vout->p_sys->hbrush; /* background color */ wc.hbrBackground = GetStockObject(BLACK_BRUSH); /* background color */
wc.lpszMenuName = NULL; /* no menu */ wc.lpszMenuName = NULL; /* no menu */
wc.lpszClassName = "VLC DirectX"; /* use a special class */ wc.lpszClassName = "VLC DirectX"; /* use a special class */
wc.hIconSm = vlc_icon; /* load the vlc small icon */ wc.hIconSm = vlc_icon; /* load the vlc small icon */
...@@ -373,13 +346,6 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -373,13 +346,6 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
{ {
WNDCLASS wndclass; WNDCLASS wndclass;
/* Free window background brush */
if( p_vout->p_sys->hbrush )
{
DeleteObject( p_vout->p_sys->hbrush );
p_vout->p_sys->hbrush = NULL;
}
if( vlc_icon ) if( vlc_icon )
{ {
DestroyIcon( vlc_icon ); DestroyIcon( vlc_icon );
...@@ -408,7 +374,8 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -408,7 +374,8 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
p_vout->p_sys->hwnd = p_vout->p_sys->hwnd =
CreateWindow( "VLC DirectX", /* name of window class */ CreateWindow( "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, /* window style */ WS_OVERLAPPEDWINDOW | WS_SIZEBOX | WS_VISIBLE |
WS_CLIPCHILDREN, /* window style */
CW_USEDEFAULT, /* default X coordinate */ CW_USEDEFAULT, /* default X coordinate */
0, /* default Y coordinate */ 0, /* default Y coordinate */
rect_window.right - rect_window.left, /* window width */ rect_window.right - rect_window.left, /* window width */
...@@ -425,15 +392,20 @@ static int DirectXCreateWindow( vout_thread_t *p_vout ) ...@@ -425,15 +392,20 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
} }
} }
/* Now display the window */
ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
/* Create video sub-window. This sub window will always exactly match
* the size of the video, which allows us to use crazy overlay colorkeys
* without having them shown outside of the video area. */
SendMessage( p_vout->p_sys->hwnd, WM_VLC_CREATE_VIDEO_WIN, 0, 0 );
/* Append a "Always On Top" entry in the system menu */ /* Append a "Always On Top" entry in the system menu */
hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE ); hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
AppendMenu( hMenu, MF_SEPARATOR, 0, "" ); AppendMenu( hMenu, MF_SEPARATOR, 0, "" );
AppendMenu( hMenu, MF_STRING | MF_UNCHECKED, AppendMenu( hMenu, MF_STRING | MF_UNCHECKED,
IDM_TOGGLE_ON_TOP, "Always on &Top" ); IDM_TOGGLE_ON_TOP, "Always on &Top" );
/* Now display the window */
ShowWindow( p_vout->p_sys->hwnd, SW_SHOW );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -512,6 +484,9 @@ void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force ) ...@@ -512,6 +484,9 @@ void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
vout_PlacePicture( p_vout, rect.right, rect.bottom, vout_PlacePicture( p_vout, rect.right, rect.bottom,
&i_x, &i_y, &i_width, &i_height ); &i_x, &i_y, &i_width, &i_height );
SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,
i_x, i_y, i_width, i_height, 0 );
/* Destination image position and dimensions */ /* Destination image position and dimensions */
rect_dest.left = point.x + i_x; rect_dest.left = point.x + i_x;
rect_dest.right = rect_dest.left + i_width; rect_dest.right = rect_dest.left + i_width;
...@@ -523,8 +498,7 @@ void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force ) ...@@ -523,8 +498,7 @@ void DirectXUpdateRects( vout_thread_t *p_vout, vlc_bool_t b_force )
* display size so we need to do it otherwise it will fail */ * display size so we need to do it otherwise it will fail */
/* Clip the destination window */ /* Clip the destination window */
IntersectRect( &rect_dest_clipped, IntersectRect( &rect_dest_clipped, &rect_dest,
&rect_dest,
&p_vout->p_sys->rect_display ); &p_vout->p_sys->rect_display );
#if 0 #if 0
...@@ -667,24 +641,24 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message, ...@@ -667,24 +641,24 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
} }
break; break;
case WM_ERASEBKGND: case WM_VLC_CREATE_VIDEO_WIN:
if( !p_vout->p_sys->b_using_overlay ) /* Create video sub-window */
p_vout->p_sys->hvideownd =
CreateWindow( "STATIC", "", /* window class and title bar text */
WS_CHILD | WS_VISIBLE, /* window style */
CW_USEDEFAULT, CW_USEDEFAULT, /* default coordinates */
CW_USEDEFAULT, CW_USEDEFAULT,
hwnd, /* parent window */
NULL, GetModuleHandle(NULL), NULL );
if( !p_vout->p_sys->hvideownd )
{ {
/* We want to eliminate unnecessary background redraws which create msg_Warn( p_vout, "Can create video sub-window" );
* an annoying flickering */ }
int i_width, i_height, i_x, i_y; else
RECT rect_temp; {
GetClipBox( (HDC)wParam, &rect_temp ); SetWindowLong( p_vout->p_sys->hvideownd,
#if 0 GWL_WNDPROC, (LONG)DefWindowProc );
msg_Dbg( p_vout, "WinProc WM_ERASEBKGND %i,%i,%i,%i",
rect_temp.left, rect_temp.top,
rect_temp.right, rect_temp.bottom );
#endif
vout_PlacePicture( p_vout, p_vout->p_sys->i_window_width,
p_vout->p_sys->i_window_height,
&i_x, &i_y, &i_width, &i_height );
ExcludeClipRect( (HDC)wParam, i_x, i_y,
i_x + i_width, i_y + i_height );
} }
break; break;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout.h: Windows DirectX video output header file * vout.h: Windows DirectX video output header file
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vout.h,v 1.7 2003/10/25 00:49:14 sam Exp $ * $Id: vout.h,v 1.8 2003/11/19 23:44:35 gbazin Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -45,9 +45,9 @@ struct vout_sys_t ...@@ -45,9 +45,9 @@ struct vout_sys_t
LPDIRECTDRAWSURFACE2 p_current_surface; /* surface currently displayed */ LPDIRECTDRAWSURFACE2 p_current_surface; /* surface currently displayed */
LPDIRECTDRAWCLIPPER p_clipper; /* clipper used for blitting */ LPDIRECTDRAWCLIPPER p_clipper; /* clipper used for blitting */
HINSTANCE hddraw_dll; /* handle of the opened ddraw dll */ HINSTANCE hddraw_dll; /* handle of the opened ddraw dll */
HBRUSH hbrush; /* window backgound brush (color) */
HWND hwnd; /* Handle of the main window */ HWND hwnd; /* Handle of the main window */
HWND hvideownd; /* Handle of the video sub-window */
HWND hparent; /* Handle of the parent window */ HWND hparent; /* Handle of the parent window */
WNDPROC pf_wndproc; /* Window handling callback */ WNDPROC pf_wndproc; /* Window handling callback */
...@@ -118,4 +118,5 @@ void DirectXUpdateRects ( vout_thread_t *p_vout, vlc_bool_t b_force ); ...@@ -118,4 +118,5 @@ void DirectXUpdateRects ( vout_thread_t *p_vout, vlc_bool_t b_force );
* Constants * Constants
*****************************************************************************/ *****************************************************************************/
#define WM_VLC_HIDE_MOUSE WM_APP #define WM_VLC_HIDE_MOUSE WM_APP
#define WM_VLC_CREATE_VIDEO_WIN WM_APP + 1
#define IDM_TOGGLE_ON_TOP WM_USER + 1 #define IDM_TOGGLE_ON_TOP WM_USER + 1
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