Commit 0c6f4bc9 authored by Sam Hocevar's avatar Sam Hocevar

  * Lots of DirectX plugin fixes by Gildas Bazin.
  * Compilation fix in message queue mode.
parent a78e34d0
...@@ -41,7 +41,7 @@ typedef struct module_symbols_s ...@@ -41,7 +41,7 @@ typedef struct module_symbols_s
void ( * intf_Msg ) ( char *, ... ); void ( * intf_Msg ) ( char *, ... );
void ( * intf_ErrMsg ) ( char *, ... ); void ( * intf_ErrMsg ) ( char *, ... );
void ( * intf_WarnMsg ) ( int, char *, ... ); void ( * intf_WarnMsg ) ( int, char *, ... );
void ( * intf_FlushMsg )( void ); void ( * intf_WarnMsgImm ) ( int, char *, ... );
int ( * intf_PlaylistAdd ) ( struct playlist_s *, int, const char* ); int ( * intf_PlaylistAdd ) ( struct playlist_s *, int, const char* );
int ( * intf_PlaylistDelete ) ( struct playlist_s *, int ); int ( * intf_PlaylistDelete ) ( struct playlist_s *, int );
...@@ -135,7 +135,7 @@ typedef struct module_symbols_s ...@@ -135,7 +135,7 @@ typedef struct module_symbols_s
(p_symbols)->intf_Msg = intf_Msg; \ (p_symbols)->intf_Msg = intf_Msg; \
(p_symbols)->intf_ErrMsg = intf_ErrMsg; \ (p_symbols)->intf_ErrMsg = intf_ErrMsg; \
(p_symbols)->intf_WarnMsg = intf_WarnMsg; \ (p_symbols)->intf_WarnMsg = intf_WarnMsg; \
(p_symbols)->intf_FlushMsg = intf_FlushMsg; \ (p_symbols)->intf_WarnMsgImm = intf_WarnMsgImm; \
(p_symbols)->intf_PlaylistAdd = intf_PlaylistAdd; \ (p_symbols)->intf_PlaylistAdd = intf_PlaylistAdd; \
(p_symbols)->intf_PlaylistDelete = intf_PlaylistDelete; \ (p_symbols)->intf_PlaylistDelete = intf_PlaylistDelete; \
(p_symbols)->intf_PlaylistNext = intf_PlaylistNext; \ (p_symbols)->intf_PlaylistNext = intf_PlaylistNext; \
...@@ -203,7 +203,7 @@ extern module_symbols_t* p_symbols; ...@@ -203,7 +203,7 @@ extern module_symbols_t* p_symbols;
# define intf_Msg p_symbols->intf_Msg # define intf_Msg p_symbols->intf_Msg
# define intf_ErrMsg p_symbols->intf_ErrMsg # define intf_ErrMsg p_symbols->intf_ErrMsg
# define intf_WarnMsg p_symbols->intf_WarnMsg # define intf_WarnMsg p_symbols->intf_WarnMsg
# define intf_FlushMsg p_symbols->intf_FlushMsg # define intf_WarnMsgImm p_symbols->intf_WarnMsgImm
# define intf_PlaylistAdd(a,b,c) p_symbols->intf_PlaylistAdd(a,b,c) # define intf_PlaylistAdd(a,b,c) p_symbols->intf_PlaylistAdd(a,b,c)
# define intf_PlaylistDelete(a,b) p_symbols->intf_PlaylistDelete(a,b) # define intf_PlaylistDelete(a,b) p_symbols->intf_PlaylistDelete(a,b)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout_directx.c: Windows DirectX video output display method * vout_directx.c: Windows DirectX video output display method
***************************************************************************** *****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN * Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vout_directx.c,v 1.2 2001/06/03 12:47:21 sam Exp $ * $Id: vout_directx.c,v 1.3 2001/06/08 20:03:15 sam Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -25,13 +25,21 @@ ...@@ -25,13 +25,21 @@
#include "modules_inner.h" #include "modules_inner.h"
/* This is a list of what needs to be fixed: /* This is a list of what needs to be fixed:
*
* When the option: "Display full screen when dragging window" is enabled in
* Windows display properties, the overlay surface coordinates won't be updated
* (but it won't crash anymore ;-) I know where the problem is in the code, but * I just don't know yet of a nice way to fix it.
*
* When you move part of the video window outside the physical display, the
* overlay surface coordinates are not updated anymore. This comes from the
* directdraw UpdateOverlay function which doesn't like negative coordinates.
* *
* For now, this plugin only works when YUV overlay is supported (which it * For now, this plugin only works when YUV overlay is supported (which it
* should be nowadays on most of the video cards under Windows)... * should be nowadays on most of the video cards under Windows)...
* *
* The overlay doesn't use double-buffering. * The overlay doesn't use double-buffering.
* *
* Use Shane Harper's optimizations for YUV * Port this plugin to Video Output IV
*/ */
/***************************************************************************** /*****************************************************************************
...@@ -45,6 +53,7 @@ ...@@ -45,6 +53,7 @@
#include <string.h> /* strerror() */ #include <string.h> /* strerror() */
#include <windows.h> #include <windows.h>
#include <windowsx.h>
#include <directx.h> #include <directx.h>
#include "config.h" #include "config.h"
...@@ -64,10 +73,6 @@ ...@@ -64,10 +73,6 @@
#include "modules.h" #include "modules.h"
#include "modules_export.h" #include "modules_export.h"
#define OVERLAY_COLOR_KEY 1 /* color on top of which the overlay will be
* displayed. 1 should be almost black but
* not black (which is too common a color) */
/***************************************************************************** /*****************************************************************************
* vout_sys_t: video output DirectX method descriptor * vout_sys_t: video output DirectX method descriptor
***************************************************************************** *****************************************************************************
...@@ -81,14 +86,16 @@ typedef struct vout_sys_s ...@@ -81,14 +86,16 @@ typedef struct vout_sys_s
LPDIRECTDRAWSURFACE p_display; /* display device */ LPDIRECTDRAWSURFACE p_display; /* display device */
LPDIRECTDRAWSURFACE p_overlay; /* overlay device */ LPDIRECTDRAWSURFACE p_overlay; /* overlay device */
LPDIRECTDRAWCLIPPER p_clipper; /* clipper */ LPDIRECTDRAWCLIPPER p_clipper; /* clipper */
HWND hwnd; /* Handle of the main */ HBRUSH hbrush; /* window backgound brush (color) */
/* window */ HWND hwnd; /* Handle of the main window */
int i_image_width; /* size of the decoded image */ int i_image_width; /* size of the decoded image */
int i_image_height; int i_image_height;
int i_window_width; /* size of the displayed image */ int i_window_width; /* size of the displayed image */
int i_window_height; int i_window_height;
int i_colorkey; /* colorkey used to display the overlay */
boolean_t b_display_enabled; boolean_t b_display_enabled;
boolean_t b_overlay; boolean_t b_overlay;
boolean_t b_cursor; boolean_t b_cursor;
...@@ -118,7 +125,6 @@ static int WinDXInitDDraw ( vout_thread_t *p_vout ); ...@@ -118,7 +125,6 @@ static int WinDXInitDDraw ( vout_thread_t *p_vout );
static int WinDXCreateDisplay ( vout_thread_t *p_vout ); static int WinDXCreateDisplay ( vout_thread_t *p_vout );
static int WinDXCreateYUVOverlay ( vout_thread_t *p_vout ); static int WinDXCreateYUVOverlay ( vout_thread_t *p_vout );
static int WinDXUpdateOverlay ( vout_thread_t *p_vout ); static int WinDXUpdateOverlay ( vout_thread_t *p_vout );
static int WinDXClipOverlay ( vout_thread_t *p_vout );
static void WinDXCloseDDraw ( vout_thread_t *p_vout ); static void WinDXCloseDDraw ( vout_thread_t *p_vout );
static void WinDXCloseWindow ( vout_thread_t *p_vout ); static void WinDXCloseWindow ( vout_thread_t *p_vout );
static void WinDXCloseDisplay ( vout_thread_t *p_vout ); static void WinDXCloseDisplay ( vout_thread_t *p_vout );
...@@ -171,11 +177,18 @@ static int vout_Create( vout_thread_t *p_vout ) ...@@ -171,11 +177,18 @@ static int vout_Create( vout_thread_t *p_vout )
return( 1 ); return( 1 );
} }
/* Initialisations */
p_vout->p_sys->p_ddobject = NULL;
p_vout->p_sys->p_display = NULL;
p_vout->p_sys->p_overlay = NULL;
p_vout->p_sys->p_clipper = NULL;
p_vout->p_sys->hbrush = INVALID_HANDLE_VALUE;
p_vout->p_sys->hwnd = INVALID_HANDLE_VALUE;
p_vout->p_sys->b_cursor = 1; /* TODO should be done with a main_GetInt.. */ p_vout->p_sys->b_cursor = 1; /* TODO should be done with a main_GetInt.. */
p_vout->p_sys->b_cursor_autohidden = 0; p_vout->p_sys->b_cursor_autohidden = 0;
p_vout->p_sys->b_display_enabled = 0; p_vout->p_sys->b_display_enabled = 0;
p_vout->p_sys->i_lastmoved = mdate(); p_vout->p_sys->i_lastmoved = mdate();
p_vout->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR, p_vout->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR,
...@@ -251,6 +264,7 @@ static void vout_End( vout_thread_t *p_vout ) ...@@ -251,6 +264,7 @@ static void vout_End( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void vout_Destroy( vout_thread_t *p_vout ) static void vout_Destroy( vout_thread_t *p_vout )
{ {
intf_WarnMsg( 3, "vout: vout_Destroy" );
WinDXCloseDisplay( p_vout ); WinDXCloseDisplay( p_vout );
WinDXCloseDDraw( p_vout ); WinDXCloseDDraw( p_vout );
WinDXCloseWindow( p_vout ); WinDXCloseWindow( p_vout );
...@@ -273,6 +287,7 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -273,6 +287,7 @@ static int vout_Manage( vout_thread_t *p_vout )
{ {
MSG msg; MSG msg;
WINDOWPLACEMENT window_placement; WINDOWPLACEMENT window_placement;
boolean_t b_dispatch_msg = TRUE;
while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{ {
...@@ -280,6 +295,12 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -280,6 +295,12 @@ static int vout_Manage( vout_thread_t *p_vout )
{ {
switch( msg.message ) switch( msg.message )
{ {
case WM_CLOSE:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_CLOSE" );
p_vout->b_die = 1;
break;
case WM_QUIT: case WM_QUIT:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_QUIT" ); intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_QUIT" );
p_main->p_intf->b_die = 1; p_main->p_intf->b_die = 1;
...@@ -289,24 +310,65 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -289,24 +310,65 @@ static int vout_Manage( vout_thread_t *p_vout )
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOVE" ); intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOVE" );
if( !p_vout->b_need_render ) if( !p_vout->b_need_render )
{ {
WinDXUpdateOverlay( p_vout ); p_vout->i_changes |= VOUT_SIZE_CHANGE;
} }
/* don't create a never ending loop */ /* don't create a never ending loop */
return( 0 ); b_dispatch_msg = FALSE;
break; break;
case WM_PAINT: case WM_APP:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_PAINT" ); intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_APP" );
if( !p_vout->b_need_render ) if( !p_vout->b_need_render )
{ {
WinDXClipOverlay( p_vout ); p_vout->i_changes |= VOUT_SIZE_CHANGE;
} }
/* don't create a never ending loop */ /* don't create a never ending loop */
return( 0 ); b_dispatch_msg = FALSE;
break;
case WM_PAINT:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_PAINT" );
break;
case WM_ERASEBKGND:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_ERASEBKGND" );
break;
case WM_MOUSEMOVE:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOUSEMOVE" );
if( p_vout->p_sys->b_cursor )
{
if( p_vout->p_sys->b_cursor_autohidden )
{
p_vout->p_sys->b_cursor_autohidden = 0;
p_vout->p_sys->i_lastmoved = mdate();
ShowCursor( TRUE );
}
else
{
p_vout->p_sys->i_lastmoved = mdate();
}
}
break;
case WM_KEYDOWN:
/* the key events are first processed here. The next
* message processed by this main message loop will be the
* char translation of the key event */
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_KEYDOWN" );
switch( msg.wParam )
{
case VK_ESCAPE:
case VK_F12:
p_main->p_intf->b_die = 1;
break;
}
TranslateMessage(&msg);
b_dispatch_msg = FALSE;
break; break;
case WM_CHAR: case WM_CHAR:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_CHAR" ); intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_CHAR" );
switch( msg.wParam ) switch( msg.wParam )
{ {
case 'q': case 'q':
...@@ -341,11 +403,20 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -341,11 +403,20 @@ static int vout_Manage( vout_thread_t *p_vout )
} }
default: default:
intf_WarnMsg( 3, "vout: WinDX vout_Manage WM Default %i",
msg.message );
break; break;
} }
/* don't create a never ending loop */
if( b_dispatch_msg )
{
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
b_dispatch_msg = TRUE;
}
else else
{ {
return( 1 ); return( 1 );
...@@ -354,6 +425,16 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -354,6 +425,16 @@ static int vout_Manage( vout_thread_t *p_vout )
} }
/*
* Size Change
*/
if( p_vout->i_changes & VOUT_SIZE_CHANGE )
{
intf_WarnMsg( 3, "vout: WinDX vout_Manage Size Change" );
WinDXUpdateOverlay( p_vout );
p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
}
/* /*
* Fullscreen change * Fullscreen change
*/ */
...@@ -387,6 +468,27 @@ static int vout_Manage( vout_thread_t *p_vout ) ...@@ -387,6 +468,27 @@ static int vout_Manage( vout_thread_t *p_vout )
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE; p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
} }
/*
* Pointer change
*/
if( ! p_vout->p_sys->b_cursor_autohidden &&
( mdate() - p_vout->p_sys->i_lastmoved > 2000000 ) )
{
/* Hide the mouse automatically */
p_vout->p_sys->b_cursor_autohidden = 1;
ShowCursor( FALSE );
}
if( p_vout->i_changes & VOUT_CURSOR_CHANGE )
{
p_vout->p_sys->b_cursor = ! p_vout->p_sys->b_cursor;
ShowCursor( p_vout->p_sys->b_cursor &&
! p_vout->p_sys->b_cursor_autohidden );
p_vout->i_changes &= ~VOUT_CURSOR_CHANGE;
}
return( 0 ); return( 0 );
} }
...@@ -489,6 +591,7 @@ static void vout_Display( vout_thread_t *p_vout ) ...@@ -489,6 +591,7 @@ static void vout_Display( vout_thread_t *p_vout )
* when the Pitch does not equal the width of the picture */ * when the Pitch does not equal the width of the picture */
for( i=0; i < ddsd.dwHeight/2; i++) for( i=0; i < ddsd.dwHeight/2; i++)
{ {
#ifdef NONAMELESSUNION
/* copy Y, we copy two lines at once */ /* copy Y, we copy two lines at once */
memcpy(ddsd.lpSurface + i*2*ddsd.u1.lPitch, memcpy(ddsd.lpSurface + i*2*ddsd.u1.lPitch,
p_vout->p_rendered_pic->p_y + i*2*i_image_width, p_vout->p_rendered_pic->p_y + i*2*i_image_width,
...@@ -507,6 +610,27 @@ static void vout_Display( vout_thread_t *p_vout ) ...@@ -507,6 +610,27 @@ static void vout_Display( vout_thread_t *p_vout )
+ i * ddsd.u1.lPitch/2, + i * ddsd.u1.lPitch/2,
p_vout->p_rendered_pic->p_u + i*i_image_width/2, p_vout->p_rendered_pic->p_u + i*i_image_width/2,
i_image_width/2); i_image_width/2);
#else
/* copy Y, we copy two lines at once */
memcpy(ddsd.lpSurface + i*2*ddsd.lPitch,
p_vout->p_rendered_pic->p_y + i*2*i_image_width,
i_image_width);
memcpy(ddsd.lpSurface + (i*2+1)*ddsd.lPitch,
p_vout->p_rendered_pic->p_y + (i*2+1)*i_image_width,
i_image_width);
/* then V */
memcpy((ddsd.lpSurface + ddsd.dwHeight * ddsd.lPitch)
+ i * ddsd.lPitch/2,
p_vout->p_rendered_pic->p_v + i*i_image_width/2,
i_image_width/2);
/* and U */
memcpy((ddsd.lpSurface + ddsd.dwHeight * ddsd.lPitch)
+ (ddsd.dwHeight * ddsd.lPitch/4)
+ i * ddsd.lPitch/2,
p_vout->p_rendered_pic->p_u + i*i_image_width/2,
i_image_width/2);
#endif /* NONAMELESSUNION */
} }
/* Unlock the Surface */ /* Unlock the Surface */
...@@ -538,44 +662,25 @@ long FAR PASCAL WinDXEventProc( HWND hwnd, UINT message, ...@@ -538,44 +662,25 @@ long FAR PASCAL WinDXEventProc( HWND hwnd, UINT message,
switch( message ) switch( message )
{ {
case WM_ACTIVATEAPP: case WM_ACTIVATE:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_ACTIVEAPP" ); intf_WarnMsg( 3, "vout: WinDX WinProc WM_ACTIVED" );
break;
case WM_SETCURSOR:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_SETCURSOR" );
/* turn the cursor off by setting it's value to NULL */
SetCursor(NULL);
break; break;
case WM_CREATE: case WM_CREATE:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_CREATE" ); intf_WarnMsg( 3, "vout: WinDX WinProc WM_CREATE" );
break; break;
/* test your key states in this case */ /* the user wants to close the window */
case WM_KEYDOWN: case WM_CLOSE:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_KEYDOWN" ); intf_WarnMsg( 3, "vout: WinDX WinProc WM_CLOSE" );
switch( wParam )
{
case VK_ESCAPE:
case VK_F12:
PostMessage(hwnd,WM_CLOSE,0,0);
break;
}
break; break;
/* this case is touched when the application is shutting down */ /* the window has been closed so shut down everything now */
case WM_DESTROY: case WM_DESTROY:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_DESTROY" ); intf_WarnMsg( 3, "vout: WinDX WinProc WM_DESTROY" );
PostQuitMessage( 0 ); PostQuitMessage( 0 );
break; break;
case WM_QUIT:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_QUIT" );
break;
case WM_SYSCOMMAND: case WM_SYSCOMMAND:
switch (wParam) switch (wParam)
{ {
...@@ -587,11 +692,40 @@ long FAR PASCAL WinDXEventProc( HWND hwnd, UINT message, ...@@ -587,11 +692,40 @@ long FAR PASCAL WinDXEventProc( HWND hwnd, UINT message,
break; break;
case WM_MOVE: case WM_MOVE:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVE" );
break;
case WM_SIZE: case WM_SIZE:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_SIZE" );
break;
case WM_MOVING:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVING" );
break;
case WM_SIZING:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_SIZING" );
break;
case WM_WINDOWPOSCHANGED: case WM_WINDOWPOSCHANGED:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVE, WMSIZE" ); intf_WarnMsg( 3, "vout: WinDX WinProc WM_WINDOWPOSCHANGED" );
PostMessage(hwnd,WM_MOVE,0,0); PostMessage( NULL, WM_APP, 0, 0);
break;
case WM_WINDOWPOSCHANGING:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_WINDOWPOSCHANGING" );
break;
case WM_PAINT:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_PAINT" );
break;
case WM_ERASEBKGND:
intf_WarnMsg( 3, "vout: WinDX WinProc WM_ERASEBKGND" );
break;
default:
intf_WarnMsg( 3, "vout: WinDX WinProc WM Default %i", message );
break; break;
} }
...@@ -610,12 +744,39 @@ static int WinDXCreateWindow( vout_thread_t *p_vout ) ...@@ -610,12 +744,39 @@ static int WinDXCreateWindow( vout_thread_t *p_vout )
HINSTANCE hInstance; HINSTANCE hInstance;
WNDCLASS wc; /* window class components */ WNDCLASS wc; /* window class components */
RECT rect_window; RECT rect_window;
COLORREF colorkey;
HDC hdc;
intf_WarnMsg( 3, "vout: WinDX WinDXCreateWindow" ); intf_WarnMsg( 3, "vout: WinDX WinDXCreateWindow" );
/* 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( GetDesktopWindow() );
for( colorkey = 1; colorkey < 0xFF /*all shades of red*/; colorkey++ )
{
if( colorkey == GetNearestColor( hdc, colorkey ) )
break;
}
intf_WarnMsg( 3, "vout: WinDXCreateWindow background color:%i", colorkey );
ReleaseDC( p_vout->p_sys->hwnd, hdc );
/* create the actual brush */
p_vout->p_sys->hbrush = CreateSolidBrush(colorkey);
p_vout->p_sys->i_colorkey = (int)colorkey;
/* fill in the window class structure */ /* fill in the window class structure */
wc.style = 0; /* no special styles */ wc.style = 0; /* no special styles */
wc.lpfnWndProc = (WNDPROC)WinDXEventProc; /* event handler */ wc.lpfnWndProc = (WNDPROC)WinDXEventProc; /* event handler */
...@@ -624,7 +785,7 @@ static int WinDXCreateWindow( vout_thread_t *p_vout ) ...@@ -624,7 +785,7 @@ static int WinDXCreateWindow( vout_thread_t *p_vout )
wc.hInstance = hInstance; /* instance */ wc.hInstance = hInstance; /* instance */
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); /* load a default icon */ wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); /* load a default icon */
wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* load a default cursor */ wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* load a default cursor */
wc.hbrBackground = NULL; /* redraw our own bg */ wc.hbrBackground = p_vout->p_sys->hbrush; /* 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 */
...@@ -743,6 +904,7 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout ) ...@@ -743,6 +904,7 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout )
return( 1 ); return( 1 );
} }
#if 0
/* Now create a clipper for our window. /* Now create a clipper for our window.
* This clipper prevents us to modify by mistake anything on the screen * This clipper prevents us to modify by mistake anything on the screen
* (primary surface) which doesn't belong to our window */ * (primary surface) which doesn't belong to our window */
...@@ -775,7 +937,7 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout ) ...@@ -775,7 +937,7 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout )
p_vout->p_sys->p_display = NULL; p_vout->p_sys->p_display = NULL;
return( 1 ); return( 1 );
} }
#endif
/* Probe the capabilities of the hardware */ /* Probe the capabilities of the hardware */
/* This is just an indication of whever or not we'll support overlay, /* This is just an indication of whever or not we'll support overlay,
...@@ -806,6 +968,7 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout ) ...@@ -806,6 +968,7 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout )
bHasOverlay, bHasColorKey, bCanStretch ); bHasOverlay, bHasColorKey, bCanStretch );
} }
p_vout->p_sys->p_overlay = NULL;
if( bHasOverlay && bHasColorKey && bCanStretch ) if( bHasOverlay && bHasColorKey && bCanStretch )
{ {
if( !WinDXCreateYUVOverlay( p_vout ) ) if( !WinDXCreateYUVOverlay( p_vout ) )
...@@ -850,6 +1013,8 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout ) ...@@ -850,6 +1013,8 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout )
/* Set thread information */ /* Set thread information */
p_vout->i_width = ddsd.dwWidth; p_vout->i_width = ddsd.dwWidth;
p_vout->i_height = ddsd.dwHeight; p_vout->i_height = ddsd.dwHeight;
#ifdef NONAMELESSUNION
p_vout->i_bytes_per_line = ddsd.u1.lPitch; p_vout->i_bytes_per_line = ddsd.u1.lPitch;
p_vout->i_screen_depth = ddsd.ddpfPixelFormat.u1.dwRGBBitCount; p_vout->i_screen_depth = ddsd.ddpfPixelFormat.u1.dwRGBBitCount;
...@@ -858,6 +1023,17 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout ) ...@@ -858,6 +1023,17 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout )
p_vout->i_red_mask = ddsd.ddpfPixelFormat.u2.dwRBitMask; p_vout->i_red_mask = ddsd.ddpfPixelFormat.u2.dwRBitMask;
p_vout->i_green_mask = ddsd.ddpfPixelFormat.u3.dwGBitMask; p_vout->i_green_mask = ddsd.ddpfPixelFormat.u3.dwGBitMask;
p_vout->i_blue_mask = ddsd.ddpfPixelFormat.u4.dwBBitMask; p_vout->i_blue_mask = ddsd.ddpfPixelFormat.u4.dwBBitMask;
#else
p_vout->i_bytes_per_line = ddsd.lPitch;
p_vout->i_screen_depth = ddsd.ddpfPixelFormat.dwRGBBitCount;
p_vout->i_bytes_per_pixel = ddsd.ddpfPixelFormat.dwRGBBitCount/8;
p_vout->i_red_mask = ddsd.ddpfPixelFormat.dwRBitMask;
p_vout->i_green_mask = ddsd.ddpfPixelFormat.dwGBitMask;
p_vout->i_blue_mask = ddsd.ddpfPixelFormat.dwBBitMask;
#endif /* NONAMELESSUNION */
/* Unlock the Surface */ /* Unlock the Surface */
dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_display, dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_display,
...@@ -896,7 +1072,11 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout ) ...@@ -896,7 +1072,11 @@ static int WinDXCreateDisplay( vout_thread_t *p_vout )
/* Set thread information */ /* Set thread information */
p_vout->i_width = ddsd.dwWidth; p_vout->i_width = ddsd.dwWidth;
p_vout->i_height = ddsd.dwHeight; p_vout->i_height = ddsd.dwHeight;
#ifdef NONAMELESSUNION
p_vout->i_bytes_per_line = ddsd.u1.lPitch; p_vout->i_bytes_per_line = ddsd.u1.lPitch;
#else
p_vout->i_bytes_per_line = ddsd.lPitch;
#endif /* NONAMELESSUNION */
/* Unlock the Surface */ /* Unlock the Surface */
dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_overlay, dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_overlay,
...@@ -926,15 +1106,19 @@ static int WinDXCreateYUVOverlay( vout_thread_t *p_vout ) ...@@ -926,15 +1106,19 @@ static int WinDXCreateYUVOverlay( vout_thread_t *p_vout )
* A color key is used to determine whether or not the overlay will be * A color key is used to determine whether or not the overlay will be
* displayed, ie the overlay will be displayed in place of the primary * displayed, ie the overlay will be displayed in place of the primary
* surface wherever the primary surface will have this color. * surface wherever the primary surface will have this color.
* This color will be painted by WinDXClipOverlay which in turn is called * The video window has been created with a background of this color so
* by a WM_PAINT event */ * the overlay will be only displayed on top of this window */
memset( &ddsd, 0, sizeof( DDSURFACEDESC )); memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2'); ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2');
#ifdef NONAMELESSUNION
ddsd.ddpfPixelFormat.u1.dwYUVBitCount = 16; ddsd.ddpfPixelFormat.u1.dwYUVBitCount = 16;
#else
ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
#endif
ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.dwFlags = DDSD_CAPS | ddsd.dwFlags = DDSD_CAPS |
...@@ -951,6 +1135,7 @@ static int WinDXCreateYUVOverlay( vout_thread_t *p_vout ) ...@@ -951,6 +1135,7 @@ static int WinDXCreateYUVOverlay( vout_thread_t *p_vout )
if( dxresult != DD_OK ) if( dxresult != DD_OK )
{ {
intf_ErrMsg( "vout error: can't create overlay surface." ); intf_ErrMsg( "vout error: can't create overlay surface." );
p_vout->p_sys->p_overlay = NULL;
} }
else else
{ {
...@@ -977,9 +1162,12 @@ static int WinDXCreateYUVOverlay( vout_thread_t *p_vout ) ...@@ -977,9 +1162,12 @@ static int WinDXCreateYUVOverlay( vout_thread_t *p_vout )
static int WinDXUpdateOverlay( vout_thread_t *p_vout ) static int WinDXUpdateOverlay( vout_thread_t *p_vout )
{ {
DDOVERLAYFX ddofx; DDOVERLAYFX ddofx;
RECT rect_window, rect_client; RECT rect_window, rect_image;
POINT point_window;
DWORD dwFlags; DWORD dwFlags;
HRESULT dxresult; HRESULT dxresult;
DWORD dw_colorkey;
DDPIXELFORMAT pixel_format;
if( p_vout->p_sys->p_overlay == NULL || p_vout->b_need_render) if( p_vout->p_sys->p_overlay == NULL || p_vout->b_need_render)
{ {
...@@ -995,13 +1183,23 @@ static int WinDXUpdateOverlay( vout_thread_t *p_vout ) ...@@ -995,13 +1183,23 @@ static int WinDXUpdateOverlay( vout_thread_t *p_vout )
/* Now get the coordinates of the window. We don't actually want the /* Now get the coordinates of the window. We don't actually want the
* window coordinates but these of the usable surface inside the window. * window coordinates but these of the usable surface inside the window.
* By specification rect_client.right = rect_client.top = 0 */ * By specification GetClientRect will always set rect_window.left and
GetWindowRect(p_vout->p_sys->hwnd, &rect_window); * rect_window.top to 0 because the Client area is always relative to the
GetClientRect(p_vout->p_sys->hwnd, &rect_client);; * container window */
rect_window.left = ( (rect_window.right - rect_window.left) - GetClientRect(p_vout->p_sys->hwnd, &rect_window);
rect_client.right ) / 2 + rect_window.left;
rect_window.right = rect_window.left + rect_client.right; point_window.x = 0;
rect_window.top = rect_window.bottom - rect_client.bottom; point_window.y = 0;
ClientToScreen(p_vout->p_sys->hwnd, &point_window);
rect_window.left = point_window.x;
rect_window.top = point_window.y;
point_window.x = rect_window.right;
point_window.y = rect_window.bottom;
ClientToScreen(p_vout->p_sys->hwnd, &point_window);
rect_window.right = point_window.x;
rect_window.bottom = point_window.y;
/* We want to keep the aspect ratio of the video */ /* We want to keep the aspect ratio of the video */
if( p_vout->b_scale ) if( p_vout->b_scale )
...@@ -1092,82 +1290,46 @@ static int WinDXUpdateOverlay( vout_thread_t *p_vout ) ...@@ -1092,82 +1290,46 @@ static int WinDXUpdateOverlay( vout_thread_t *p_vout )
} }
/* It seems we can't feed the UpdateOverlay directdraw function with
* negative values so we have to clip the computed rectangles */
/* FIXME */
/* compute the colorkey pixel value from the RGB value we've got */
memset( &pixel_format, 0, sizeof( DDPIXELFORMAT ));
pixel_format.dwSize = sizeof( DDPIXELFORMAT );
dxresult = IDirectDrawSurface_GetPixelFormat( p_vout->p_sys->p_display,
&pixel_format );
if( dxresult != DD_OK )
intf_WarnMsg( 3, "vout: WinDX GetPixelFormat failed !!" );
dw_colorkey = (DWORD)p_vout->p_sys->i_colorkey;
#ifdef NONAMELESSUNION
dw_colorkey = (DWORD)((( dw_colorkey * pixel_format.u2.dwRBitMask) / 255)
& pixel_format.u2.dwRBitMask);
#else
dw_colorkey = (DWORD)((( dw_colorkey * pixel_format.dwRBitMask) / 255)
& pixel_format.dwRBitMask);
#endif
/* Position and show the overlay */ /* Position and show the overlay */
memset(&ddofx, 0, sizeof(DDOVERLAYFX)); memset(&ddofx, 0, sizeof(DDOVERLAYFX));
ddofx.dwSize = sizeof(DDOVERLAYFX); ddofx.dwSize = sizeof(DDOVERLAYFX);
ddofx.dckDestColorkey.dwColorSpaceLowValue = OVERLAY_COLOR_KEY; ddofx.dckDestColorkey.dwColorSpaceLowValue = dw_colorkey;
ddofx.dckDestColorkey.dwColorSpaceHighValue = OVERLAY_COLOR_KEY; ddofx.dckDestColorkey.dwColorSpaceHighValue = dw_colorkey;
dwFlags = DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW; dwFlags = DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW;
dxresult = IDirectDrawSurface_UpdateOverlay(p_vout->p_sys->p_overlay, dxresult = IDirectDrawSurface_UpdateOverlay(p_vout->p_sys->p_overlay,
NULL, NULL, /*&rect_image,*/
p_vout->p_sys->p_display, p_vout->p_sys->p_display,
&rect_window, &rect_window,
dwFlags, dwFlags,
&ddofx); &ddofx);
if(dxresult != DD_OK) if(dxresult != DD_OK)
{ {
intf_WarnMsg( 3, "vout: WinDX WM_MOVE can't move or resize overlay" ); intf_WarnMsg( 3, "vout: WinDX can't move or resize overlay" );
}
return ( 0 );
}
/*****************************************************************************
* WinDXClipOveraly: Clip overlay surface on video display.
*****************************************************************************
* The overlay is displayed on top of the primary surface (which is the
* screen).
* This overlay must be clipped whenever another window is supposed to cover
* it.
* For this, we use a color key which we paint on the parts of the window
* which aren't covered by anything else. The video adapter will then only
* display the overlay on the surfaces painted with this color key.
* This function is called whenever a WM_PAINT event is generated
* (in vout_Manage).
*****************************************************************************/
static int WinDXClipOverlay( vout_thread_t *p_vout )
{
PAINTSTRUCT ps;
POINT ptClient;
RECT rectBlt;
DDBLTFX ddbfx;
if( p_vout->p_sys->p_overlay == NULL || p_vout->b_need_render)
{
intf_WarnMsg( 3, "vout: WinDX no overlay !!" );
return( 0 );
} }
BeginPaint(p_vout->p_sys->hwnd, &ps);
/* Fill the client area with colour key */
ptClient.x = ps.rcPaint.left;
ptClient.y = ps.rcPaint.top;
ClientToScreen(p_vout->p_sys->hwnd, &ptClient);
rectBlt.left = ptClient.x;
rectBlt.top = ptClient.y;
ptClient.x = ps.rcPaint.right;
ptClient.y = ps.rcPaint.bottom;
ClientToScreen(p_vout->p_sys->hwnd, &ptClient);
rectBlt.right = ptClient.x;
rectBlt.bottom = ptClient.y;
memset(&ddbfx, 0, sizeof(DDBLTFX));
ddbfx.dwSize = sizeof(DDBLTFX);
ddbfx.u5.dwFillColor = OVERLAY_COLOR_KEY;
IDirectDrawSurface_Blt(p_vout->p_sys->p_display,
&rectBlt,
NULL,
&rectBlt,
DDBLT_COLORFILL, // | DDBLT_WAIT,
&ddbfx);
EndPaint(p_vout->p_sys->hwnd, &ps);
return ( 0 ); return ( 0 );
} }
...@@ -1180,6 +1342,7 @@ static void WinDXCloseWindow( vout_thread_t *p_vout ) ...@@ -1180,6 +1342,7 @@ static void WinDXCloseWindow( vout_thread_t *p_vout )
{ {
HINSTANCE hInstance; HINSTANCE hInstance;
intf_WarnMsg( 3, "vout: WinDXCloseWindow" );
if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE ) if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE )
{ {
DestroyWindow( p_vout->p_sys->hwnd); DestroyWindow( p_vout->p_sys->hwnd);
...@@ -1190,6 +1353,12 @@ static void WinDXCloseWindow( vout_thread_t *p_vout ) ...@@ -1190,6 +1353,12 @@ static void WinDXCloseWindow( vout_thread_t *p_vout )
UnregisterClass( "VLC DirectX", /* class name */ UnregisterClass( "VLC DirectX", /* class name */
hInstance ); /* handle to application instance */ hInstance ); /* handle to application instance */
/* free window background brush */
if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE )
{
DeleteObject( p_vout->p_sys->hbrush );
p_vout->p_sys->hbrush = INVALID_HANDLE_VALUE;
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -1199,6 +1368,7 @@ static void WinDXCloseWindow( vout_thread_t *p_vout ) ...@@ -1199,6 +1368,7 @@ static void WinDXCloseWindow( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void WinDXCloseDDraw( vout_thread_t *p_vout ) static void WinDXCloseDDraw( vout_thread_t *p_vout )
{ {
intf_WarnMsg(3, "vout: WinDXCloseDDraw" );
if( p_vout->p_sys->p_ddobject != NULL ) if( p_vout->p_sys->p_ddobject != NULL )
{ {
IDirectDraw_Release(p_vout->p_sys->p_ddobject); IDirectDraw_Release(p_vout->p_sys->p_ddobject);
...@@ -1214,20 +1384,24 @@ static void WinDXCloseDDraw( vout_thread_t *p_vout ) ...@@ -1214,20 +1384,24 @@ static void WinDXCloseDDraw( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void WinDXCloseDisplay( vout_thread_t *p_vout ) static void WinDXCloseDisplay( vout_thread_t *p_vout )
{ {
intf_WarnMsg( 3, "vout: WinDXCloseDisplay" );
if( p_vout->p_sys->p_display != NULL ) if( p_vout->p_sys->p_display != NULL )
{ {
if( p_vout->p_sys->p_overlay != NULL ) if( p_vout->p_sys->p_overlay != NULL )
{ {
intf_WarnMsg( 3, "vout: WinDXCloseDisplay overlay" );
IDirectDraw_Release( p_vout->p_sys->p_overlay ); IDirectDraw_Release( p_vout->p_sys->p_overlay );
p_vout->p_sys->p_overlay = NULL; p_vout->p_sys->p_overlay = NULL;
} }
if( p_vout->p_sys->p_clipper != NULL ) if( p_vout->p_sys->p_clipper != NULL )
{ {
intf_WarnMsg( 3, "vout: WinDXCloseDisplay clipper" );
IDirectDraw_Release( p_vout->p_sys->p_clipper ); IDirectDraw_Release( p_vout->p_sys->p_clipper );
p_vout->p_sys->p_clipper = NULL; p_vout->p_sys->p_clipper = NULL;
} }
intf_WarnMsg( 3, "vout: WinDXCloseDisplay display" );
IDirectDraw_Release( p_vout->p_sys->p_display ); IDirectDraw_Release( p_vout->p_sys->p_display );
p_vout->p_sys->p_display = NULL; p_vout->p_sys->p_display = NULL;
} }
...@@ -1243,6 +1417,7 @@ static void WinDXCloseDisplay( vout_thread_t *p_vout ) ...@@ -1243,6 +1417,7 @@ static void WinDXCloseDisplay( vout_thread_t *p_vout )
*****************************************************************************/ *****************************************************************************/
static void WinDXCloseYUVOverlay( vout_thread_t *p_vout ) static void WinDXCloseYUVOverlay( vout_thread_t *p_vout )
{ {
intf_WarnMsg( 3, "vout: WinDXCloseYUVOverlay" );
if( p_vout->p_sys->p_overlay != NULL ) if( p_vout->p_sys->p_overlay != NULL )
{ {
IDirectDraw_Release( p_vout->p_sys->p_overlay ); IDirectDraw_Release( p_vout->p_sys->p_overlay );
...@@ -1250,4 +1425,3 @@ static void WinDXCloseYUVOverlay( vout_thread_t *p_vout ) ...@@ -1250,4 +1425,3 @@ static void WinDXCloseYUVOverlay( vout_thread_t *p_vout )
} }
p_vout->p_sys->b_display_enabled = 0; p_vout->p_sys->b_display_enabled = 0;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_dummy.c: dummy input plugin, to manage "vlc:***" special options * input_dummy.c: dummy input plugin, to manage "vlc:***" special options
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: input_dummy.c,v 1.1 2001/06/07 01:10:33 sam Exp $ * $Id: input_dummy.c,v 1.2 2001/06/08 20:03:16 sam Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -150,8 +150,7 @@ static void DummyOpen( input_thread_t * p_input ) ...@@ -150,8 +150,7 @@ static void DummyOpen( input_thread_t * p_input )
{ {
i_arg = atoi( psz_name + 6 ); i_arg = atoi( psz_name + 6 );
intf_WarnMsg( 1, "input: playlist command `pause %i'", i_arg ); intf_WarnMsgImm( 1, "input: playlist command `pause %i'", i_arg );
intf_FlushMsg();
msleep( i_arg * 1000000 ); msleep( i_arg * 1000000 );
return; return;
......
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