Patch for the DirectX plugin

Gildas Bazin gbazin at netcourrier.com
Mon Jun 11 09:43:36 CEST 2001


Hi,

This is yet another patch for the DirectX plugin.

Changelog:
- We don't link with the ddraw and dsound libs anymore, instead we use run-time dynamic loading for the directx DLLs.
- We now use the more recent IDirectDraw2 and IDirectDrawSurface3 interfaces (which I think correspond to DirectX version 5)
- Fixed bug where the Overlay surface was not updated if you moved the window outside the physical screen.
- In the DirectSound plugin we create a primary sound buffer, that way we don't hear anymore the cliking when starting playing a new video.
- Use the -vvv or -vvvvv options to get all the debug messages needed.
- Cosmetic changes.

Major problems left:
- The audio plugin (direct sound) is still not behaving correctly. The main problem I've got is that sometimes the sound starts playing with a few seconds of delay. I still don't know why.
- I don't know if the bug Sam reported is still there, but it may be gone now (requires testing).

Overall the directx video plugin seems pretty stable on my computer. But I really need to fix this audio problem.
I will put together a Binary package with the DirectX and GTK plugins that I will put on the videolan ftp site (this evening). If you could put this package in the download section that would be great because more people will be able to test it and report bugs. Of course you'll have to put a warning that this package is only for testing purpose.

Have a nice day,

--
Gildas

----- La messagerie itinérante sans abonnement NetCourrier -----
Web : www.netcourrier.com - Minitel : 3615 NETCOURRIER
Téléphone : 08 36 69 00 21


-- Attached file included as plaintext by Listar --

Index: configure.in
===================================================================
RCS file: /var/cvs/videolan/vlc/configure.in,v
retrieving revision 1.106
diff -u -r1.106 configure.in
--- configure.in	2001/06/07 15:27:44	1.106
+++ configure.in	2001/06/11 06:17:15
@@ -421,18 +421,18 @@
       PLUGINS="${PLUGINS} directx";
       if test "x$withval" != "xyes";
       then
-        LIB_DIRECTX="${LIB_DIRECTX} -L"$withval"/lib -lddraw -ldsound"
+        LIB_DIRECTX="${LIB_DIRECTX} -L"$withval"/lib -lgdi32 -ldxguid"
         INCLUDE="${INCLUDE} -I"$withval"/include"
       else
         AC_CHECK_HEADERS(directx.h, , [echo "Cannot find DirectX headers !"; exit])
-        LIB_DIRECTX="${LIB_DIRECTX} -L/usr/lib -lddraw -ldsound"
+        LIB_DIRECTX="${LIB_DIRECTX} -L/usr/lib -lgdi32 -ldxguid"
       fi
     fi ])
     if test "x$withval" = "x";
     then
       AC_CHECK_HEADERS(directx.h,
       [PLUGINS="${PLUGINS} directx"
-       LIB_DIRECTX="${LIB_DIRECTX} -L/usr/lib -lddraw -ldsound"])
+       LIB_DIRECTX
="${LIB_DIRECTX} -L/usr/lib -lgdi32 -ldxguid"])
     fi
 
 dnl
Index: plugins/directx/aout_directx.c
===================================================================
RCS file: /var/cvs/videolan/vlc/plugins/directx/aout_directx.c,v
retrieving revision 1.2
diff -u -r1.2 aout_directx.c
--- plugins/directx/aout_directx.c	2001/06/03 12:47:21	1.2
+++ plugins/directx/aout_directx.c	2001/06/11 06:17:15
@@ -24,7 +24,7 @@
 #define MODULE_NAME directx
 #include "modules_inner.h"
 
-/* The most important this to do for now is to fix the audio bug we've got
+/* The most important thing to do for now is to fix the audio bug we've got
  * on startup: the audio will start later than the video (sometimes) and
  * is trying to catching up with it.
  * At first sight it seems to be a scheduling problem
@@ -77,6 +77,8 @@
                                        * takes care of mixing all the
                                        * secondary buffers into the primary) */
 
+    HINSTANCE           hdsound_dll;      /* handle o
f the opened dsound dll */
+
     long l_buffer_size;                       /* secondary sound buffer size */
     long l_write_position;             /* next write position for the buffer */
 
@@ -96,7 +98,8 @@
 static void    aout_Close       ( aout_thread_t *p_aout );
 
 /* local function */
-static int windx_CreateSecondaryBuffer( aout_thread_t *p_aout );
+static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout );
+static int DirectxInitDSound( aout_thread_t *p_aout );
 
 /*****************************************************************************
  * Functions exported as capabilities. They are declared as static so that
@@ -135,11 +138,11 @@
  *****************************************************************************/
 static int aout_Open( aout_thread_t *p_aout )
 {
-#if 0
     HRESULT dsresult;
     DSBUFFERDESC dsbuffer_desc;
     WAVEFORMATEX waveformat;
-#endif
+
+    intf_WarnMsg( 3, "aout: DirectX aout_Open ");
 
    /* Allocate structure */
     p_aout->p_sys = malloc( sizeof( aout_sy
s_t ) );
@@ -162,32 +165,13 @@
     p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR,
                                               AOUT_RATE_DEFAULT );
 
-    /* Create the direct sound object */
-    if( DirectSoundCreate(NULL, &p_aout->p_sys->p_dsobject, NULL) != DS_OK )
+    /* Initialise DirectSound */
+    if( DirectxInitDSound( p_aout ) )
     {
-        intf_WarnMsg( 3, "aout: can't create a direct sound device ");
-        p_aout->p_sys->p_dsobject = NULL;
+        intf_WarnMsg( 3, "aout: can't initialise DirectSound ");
         return( 1 );
     }
 
-    /* Set DirectSound Cooperative level, ie what control we want over Windows
-     * sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the
-     * settings of the primary buffer, but also that only the sound of our
-     * application will be hearable when it will have the focus.
-     * !!! (this is not really working as intended yet because to set the
-     * cooperative level you need the window handle of your application
, and
-     * I don't know of any easy way to get it. Especially since we might play
-     * sound without any video, and so what window handle should we use ???
-     * The hack for now is to use the Desktop window handle - it seems to be
-     * working */
-    if( IDirectSound_SetCooperativeLevel(p_aout->p_sys->p_dsobject,
-                                         GetDesktopWindow(),
-                                         DSSCL_EXCLUSIVE) )
-    {
-        intf_WarnMsg( 3, "aout: can't set direct sound cooperative level ");
-    }
-
-#if 0
     /* Obtain (not create) Direct Sound primary buffer */
     memset( &dsbuffer_desc, 0, sizeof(DSBUFFERDESC) );
     dsbuffer_desc.dwSize = sizeof(DSBUFFERDESC);
@@ -240,15 +224,12 @@
         p_aout->p_sys->p_dsbuffer_primary = NULL;
         return( 1 );
     }
-#endif
 
     /* Now create the buffer that we'll actually use: the secondary buffer */
-    if( windx_CreateSecondaryBuffer( p_aout ) )
+    if( DirectxCreateSecondaryBuffer( p_aout ) )
     {
         i
ntf_WarnMsg( 3, "aout: can't create direct sound secondary buffer ");
-#if 0
         IDirectSound_Release( p_aout->p_sys->p_dsbuffer_primary );
-#endif
         IDirectSound_Release( p_aout->p_sys->p_dsobject );
         p_aout->p_sys->p_dsobject = NULL;
         p_aout->p_sys->p_dsbuffer_primary = NULL;
@@ -270,6 +251,8 @@
 {
     HRESULT dsresult;
 
+    intf_WarnMsg( 3, "aout: DirectX aout_SetFormat ");
+
     /* first release the current secondary buffer */
     if( p_aout->p_sys->p_dsbuffer != NULL )
     {
@@ -278,10 +261,10 @@
     }
 
     /* then create a new secondary buffer */
-    dsresult = windx_CreateSecondaryBuffer( p_aout );    
+    dsresult = DirectxCreateSecondaryBuffer( p_aout );    
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_SetFormat cannot create buffer");
+        intf_WarnMsg( 3, "aout: DirectX aout_SetFormat cannot create buffer");
         return( 1 );
     }
   
@@ -311,16 +294,25 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_War
nMsg( 3, "aout: WinDX aout_GetBufInfo cannot get current pos");
+        intf_WarnMsg(3,"aout: DirectX aout_GetBufInfo cannot get current pos");
         return( l_buffer_limit );
     }
+
+    /* temporary hack. When you start playing a new file, the play position
+     * doesn't start changing immediatly, even though sound is already
+     * playing from the sound card */
+    if( l_play_position == 0 )
+    { 
+       intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_buffer_limit);
+       return( l_buffer_limit );
+    }
 
-    l_result = ((p_aout->p_sys->l_write_position >= l_play_position) ?
-                (p_aout->p_sys->l_write_position - l_play_position)/2
-                : (p_aout->p_sys->l_buffer_size - l_play_position
-                    + p_aout->p_sys->l_write_position)/2 );
+    l_result = (p_aout->p_sys->l_write_position >= l_play_position) ?
+      (p_aout->p_sys->l_write_position - l_play_position) /2
+               : (p_aout->p_sys->l_buffer_size - l_play_position
+             
     + p_aout->p_sys->l_write_position) /2 ;
 
-    intf_WarnMsg( 5, "aout: WinDX aout_GetBufInfo: %li", l_result);
+    intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_result);
     return l_result;
 }
 
@@ -336,7 +328,7 @@
     long            l_play_position, l_notused, l_buffer_free_length;
     HRESULT         dsresult;
 
-    /* We want to copy data to the circular sound buffer, so first we need to
+    /* We want to copy data to the circular sound buffer, so we first need to
      * find out were in the buffer we can write our data */
     dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer,
                                                      &l_play_position,
@@ -351,22 +343,33 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play can'get buffer position");
+        intf_WarnMsg( 3, "aout: DirectX aout_Play can'get buffer position");
     }
 
     /* check that we are not overflowing the circular buffer (everything should
     
 * be alright but just in case) */
     l_buffer_free_length =  l_play_position - p_aout->p_sys->l_write_position;
     if( l_buffer_free_length <= 0 )
-        l_buffer_free_length += p_aout->p_sys->l_buffer_size  ;
+        l_buffer_free_length += p_aout->p_sys->l_buffer_size;
 
     if( i_size > l_buffer_free_length )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play buffer overflow: size %i, free %i !!!", i_size, l_buffer_free_length);
-        intf_WarnMsg( 3, "aout: WinDX aout_Play buffer overflow: writepos %i, readpos %i !!!", l_play_position, p_aout->p_sys->l_write_position);
+        intf_WarnMsg( 3, "aout: DirectX aout_Play buffer overflow: size %i, free %i !!!", i_size, l_buffer_free_length);
+        intf_WarnMsg( 3, "aout: DirectX aout_Play buffer overflow: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
         /*i_size = l_buffer_free_length;*/
+
+        /* Update the write pointer */
+        p_aout->p_sys->l_write_position = l_notused;
+
     }
+    el
se
+    {
+        intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: size %i, free %i !!!"
+                      , i_size, l_buffer_free_length);
+        intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
 
+    }
+
     /* Before copying anything, we have to lock the buffer */
     dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
                    p_aout->p_sys->l_write_position,  /* Offset of lock start */
@@ -391,7 +394,7 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play can't lock buffer");
+        intf_WarnMsg( 3, "aout: DirectX aout_Play can't lock buffer");
         return;
     }
 
@@ -423,7 +426,7 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX aout_Play can't play buffer");
+        intf_WarnMsg( 3, "aout: DirectX aout_Play can't play buffer");
         return;
     }
 
@@ -434,6 +437,9 @@
  ******************************
***********************************************/
 static void aout_Close( aout_thread_t *p_aout )
 {
+
+    intf_WarnMsg( 3, "aout: DirectX aout_Close ");
+
     /* make sure the buffer isn't playing */
     if( p_aout->p_sys->p_dsbuffer != NULL )
     {
@@ -461,6 +467,13 @@
         p_aout->p_sys->p_dsobject = NULL;
     }  
     
+    /* free DSOUND.DLL */
+    if( p_aout->p_sys->hdsound_dll != NULL )
+    {
+       FreeLibrary( p_aout->p_sys->hdsound_dll );
+       p_aout->p_sys->hdsound_dll = NULL;
+    }
+
     /* Close the Output. */
     if ( p_aout->p_sys != NULL )
     { 
@@ -469,8 +482,64 @@
     }
 }
 
+/*****************************************************************************
+ * DirectxInitDSound
+ *****************************************************************************
+ *****************************************************************************/
+static int DirectxInitDSound( aout_thread_t *p_aout )
+{
+    HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
+

+    p_aout->p_sys->hdsound_dll = LoadLibrary("DSOUND.DLL");
+    if( p_aout->p_sys->hdsound_dll == NULL )
+    {
+      intf_WarnMsg( 3, "aout: can't open DSOUND.DLL ");
+      return( 1 );
+    }
+
+    OurDirectSoundCreate = (void *)GetProcAddress( p_aout->p_sys->hdsound_dll,
+                                                   "DirectSoundCreate" );
+
+    if( OurDirectSoundCreate == NULL )
+    {
+      intf_WarnMsg( 3, "aout: GetProcAddress FAILED ");
+      FreeLibrary( p_aout->p_sys->hdsound_dll );
+      p_aout->p_sys->hdsound_dll = NULL;
+      return( 1 );
+    }
+
+    /* Create the direct sound object */
+    if( OurDirectSoundCreate(NULL, &p_aout->p_sys->p_dsobject, NULL) != DS_OK )
+    {
+        intf_WarnMsg( 3, "aout: can't create a direct sound device ");
+        p_aout->p_sys->p_dsobject = NULL;
+        FreeLibrary( p_aout->p_sys->hdsound_dll );
+        p_aout->p_sys->hdsound_dll = NULL;
+        return( 1 );
+    }
+
+    /* Set DirectSound Cooperative level, ie what control we want ov
er Windows
+     * sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the
+     * settings of the primary buffer, but also that only the sound of our
+     * application will be hearable when it will have the focus.
+     * !!! (this is not really working as intended yet because to set the
+     * cooperative level you need the window handle of your application, and
+     * I don't know of any easy way to get it. Especially since we might play
+     * sound without any video, and so what window handle should we use ???
+     * The hack for now is to use the Desktop window handle - it seems to be
+     * working */
+    if( IDirectSound_SetCooperativeLevel(p_aout->p_sys->p_dsobject,
+                                         GetDesktopWindow(),
+                                         DSSCL_EXCLUSIVE) )
+    {
+        intf_WarnMsg( 3, "aout: can't set direct sound cooperative level ");
+    }
+
+    return( 0 );
+}
+
 /**************************************************************************
***
- * windx_CreateSecondaryBuffer
+ * DirectxCreateSecondaryBuffer
  *****************************************************************************
  * This function creates the buffer we'll use to play audio.
  * In DirectSound there are two kinds of buffers:
@@ -481,7 +550,7 @@
  * Once you create a secondary buffer, you cannot change its format anymore so
  * you have to release the current and create another one.
  *****************************************************************************/
-static int windx_CreateSecondaryBuffer( aout_thread_t *p_aout )
+static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout )
 {
     WAVEFORMATEX waveformat;
     DSBUFFERDESC dsbdesc;
@@ -523,11 +592,11 @@
 
     /* backup the size of the secondary sound buffer */
     memset(&dsbcaps, 0, sizeof(DSBCAPS)); 
-    dsbcaps.dwSize = sizeof(DSBCAPS); 
+    dsbcaps.dwSize = sizeof(DSBCAPS);
     IDirectSoundBuffer_GetCaps( p_aout->p_sys->p_dsbuffer, &dsbcaps  );
     p_aout->p_sys->l_buffer_size = dsbcaps.dwBufferB
ytes;
     p_aout->p_sys->l_write_position = 0;
-    intf_WarnMsg( 3, "aout: WinDX WinDX_CreateSecondaryBuffer: %li",
+    intf_WarnMsg( 3, "aout: DirectX DirectxCreateSecondaryBuffer: %li",
                   p_aout->p_sys->l_buffer_size);
 
     /* make sure the buffer isn't playing */
@@ -546,9 +615,8 @@
     }
     if( dsresult != DS_OK )
     {
-        intf_WarnMsg( 3, "aout: WinDX CreateSecondary cannot wet current pos");
+        intf_WarnMsg(3,"aout: DirectX CreateSecondary cannot wet current pos");
     }
 
     return( 0 );
 }
-
Index: plugins/directx/vout_directx.c
===================================================================
RCS file: /var/cvs/videolan/vlc/plugins/directx/vout_directx.c,v
retrieving revision 1.3
diff -u -r1.3 vout_directx.c
--- plugins/directx/vout_directx.c	2001/06/08 20:03:15	1.3
+++ plugins/directx/vout_directx.c	2001/06/11 06:17:16
@@ -82,10 +82,11 @@
 typedef struct vout_sys_s
 {
 
-    LPDIRECTDRAW         p_ddobject;                    /* DirectDraw object */
-    LP
DIRECTDRAWSURFACE  p_display;                        /* display device */
-    LPDIRECTDRAWSURFACE  p_overlay;                        /* overlay device */
-    LPDIRECTDRAWCLIPPER  p_clipper;                               /* clipper */
+    LPDIRECTDRAW2        p_ddobject;                    /* DirectDraw object */
+    LPDIRECTDRAWSURFACE3 p_display;                        /* Display device */
+    LPDIRECTDRAWSURFACE3 p_surface;    /* surface where we display the video */
+    LPDIRECTDRAWCLIPPER  p_clipper;             /* clipper used for blitting */
+    HINSTANCE            hddraw_dll;       /* handle of the opened ddraw dll */
     HBRUSH               hbrush;           /* window backgound brush (color) */
     HWND                 hwnd;                  /* Handle of the main window */
 
@@ -103,7 +104,7 @@
     boolean_t   b_cursor_autohidden;
     mtime_t     i_lastmoved;
 
-    char       *p_windx_buf[2];                        /* Buffer information */
+    char       *p_directx_buf[2];              
        /* Buffer information */
 
 } vout_sys_t;
 
@@ -120,15 +121,15 @@
 static void vout_SetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green,
                              u16 *blue, u16 *transp );
 
-static int  WinDXCreateWindow     ( vout_thread_t *p_vout );
-static int  WinDXInitDDraw        ( vout_thread_t *p_vout );
-static int  WinDXCreateDisplay    ( vout_thread_t *p_vout );
-static int  WinDXCreateYUVOverlay ( vout_thread_t *p_vout );
-static int  WinDXUpdateOverlay    ( vout_thread_t *p_vout );
-static void WinDXCloseDDraw       ( vout_thread_t *p_vout );
-static void WinDXCloseWindow      ( vout_thread_t *p_vout );
-static void WinDXCloseDisplay     ( vout_thread_t *p_vout );
-static void WinDXCloseYUVOverlay  ( vout_thread_t *p_vout );
+static int  DirectXCreateWindow   ( vout_thread_t *p_vout );
+static int  DirectXInitDDraw      ( vout_thread_t *p_vout );
+static int  DirectXCreateDisplay  ( vout_thread_t *p_vout );
+static int  DirectXCreateSurface  ( vout_thread_t *p_vout );
+static in
t  DirectXUpdateOverlay  ( vout_thread_t *p_vout );
+static void DirectXCloseDDraw     ( vout_thread_t *p_vout );
+static void DirectXCloseWindow    ( vout_thread_t *p_vout );
+static void DirectXCloseDisplay   ( vout_thread_t *p_vout );
+static void DirectXCloseSurface   ( vout_thread_t *p_vout );
 
 /*****************************************************************************
  * Functions exported as capabilities. They are declared as static so that
@@ -154,11 +155,15 @@
  *****************************************************************************/
 static int vout_Probe( probedata_t *p_data )
 {
+
     if( TestMethod( VOUT_METHOD_VAR, "directx" ) )
     {
         return( 999 );
     }
 
+    /* Check that at least DirectX5 is installed on the computer */
+    /* Fixme */
+
     return( 400 );
 }
 
@@ -180,15 +185,16 @@
     /* 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_surface = 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->hbrush = NULL;
+    p_vout->p_sys->hwnd = NULL;
+    p_vout->p_sys->b_display_enabled = 0;
+    p_vout->b_need_render = 0;      /* by default try an YUV overlay display */
 
     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_display_enabled = 0;
     p_vout->p_sys->i_lastmoved = mdate();
 
     p_vout->b_fullscreen = main_GetIntVariable( VOUT_FULLSCREEN_VAR,
@@ -207,7 +213,7 @@
     /* Create a window for the video */
     /* Creating a window under Windows also initializes the thread's event
      * message qeue */
-    if( WinDXCreateWindow( p_vout ) )
+    if( DirectXCreateWindow( p_vout ) )
     {
         intf_ErrMsg( "vout error: can't create window" );
         free( p_vout->p_sys );
@@ -215,20 +221,20 @@
     }
 
     /* Initialise DirectDraw */
-    if(
 WinDXInitDDraw( p_vout ) )
+    if( DirectXInitDDraw( p_vout ) )
     {
         intf_ErrMsg( "vout error: can't initialise DirectDraw" );
-        WinDXCloseWindow( p_vout );
+        DirectXCloseWindow( p_vout );
         free( p_vout->p_sys );
         return ( 1 );
     }
 
-    /* create the directx display */
-    if( WinDXCreateDisplay( p_vout ) )
+    /* Create the directx display */
+    if( DirectXCreateDisplay( p_vout ) )
     {
         intf_ErrMsg( "vout error: can't initialise DirectDraw" );
-        WinDXCloseDDraw( p_vout );
-        WinDXCloseWindow( p_vout );
+        DirectXCloseDDraw( p_vout );
+        DirectXCloseWindow( p_vout );
         free( p_vout->p_sys );
         return ( 1 );
     }
@@ -265,9 +271,9 @@
 static void vout_Destroy( vout_thread_t *p_vout )
 {
     intf_WarnMsg( 3, "vout: vout_Destroy" );
-    WinDXCloseDisplay( p_vout );
-    WinDXCloseDDraw( p_vout );
-    WinDXCloseWindow( p_vout );
+    DirectXCloseDisplay( p_vout );
+    DirectXCloseDDraw( p_vout );
+    Direct
XCloseWindow( p_vout );
 
     if( p_vout->p_sys != NULL )
     {
@@ -297,17 +303,17 @@
             {
 
                 case WM_CLOSE:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_CLOSE" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_CLOSE" );
                     p_vout->b_die = 1;
                     break;
 
                 case WM_QUIT:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_QUIT" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_QUIT" );
                     p_main->p_intf->b_die = 1;
                     break;
 
                 case WM_MOVE:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOVE" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_MOVE" );
                     if( !p_vout->b_need_render )
                     {
                         p_vout->i_changes |= VOUT_SIZE_CHANGE;
@@ -317,7 +323,7 @@
                     break;
 
                 case WM_APP:
-                    intf_
WarnMsg( 3, "vout: WinDX vout_Manage WM_APP" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_APP" );
                     if( !p_vout->b_need_render )
                     {
                         p_vout->i_changes |= VOUT_SIZE_CHANGE;
@@ -327,18 +333,18 @@
                     break;
 
                 case WM_PAINT:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_PAINT" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_PAINT" );
                     break;
 
                 case WM_ERASEBKGND:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_ERASEBKGND" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_ERASEBKGND" );
                     break;
 
                 case WM_MOUSEMOVE:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_MOUSEMOVE" );
+                    intf_WarnMsg( 4, "vout: vout_Manage WM_MOUSEMOVE" );
                     if( p_vout->p_sys->b_cursor )
                     {
-                    if(
 p_vout->p_sys->b_cursor_autohidden )
+                        if( p_vout->p_sys->b_cursor_autohidden )
                         {
                             p_vout->p_sys->b_cursor_autohidden = 0;
                             p_vout->p_sys->i_lastmoved = mdate();
@@ -355,7 +361,7 @@
                     /* 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" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_KEYDOWN" );
                     switch( msg.wParam )
                     {
                         case VK_ESCAPE:
@@ -368,7 +374,7 @@
                     break;
 
                 case WM_CHAR:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM_CHAR" );
+                    intf_WarnMsg( 3, "vout: vout_Manage WM_CHAR" );
                     switch( msg.wParam )

                     {
                         case 'q':
@@ -376,11 +382,39 @@
                             p_main->p_intf->b_die = 1;
                             break;
 
-                        case 'f':
+                        case 'f':                    /* switch to fullscreen */
                         case 'F':
                             p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
                             break;
 
+                        case 'y':                      /* switch to hard YUV */
+                        case 'Y':
+                            p_vout->i_changes |= VOUT_YUV_CHANGE;
+                            break;
+                          
+                        case 'c':                        /* toggle grayscale */
+                        case 'C':
+                            p_vout->b_grayscale = ! p_vout->b_grayscale;
+                            p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
+                            break;
+                          
+           
             case 'i':                             /* toggle info */
+                        case 'I':
+                            p_vout->b_info = ! p_vout->b_info;
+                            p_vout->i_changes |= VOUT_INFO_CHANGE;
+                            break;
+
+                        case 's':                          /* toggle scaling */
+                        case 'S':
+                            p_vout->b_scale = ! p_vout->b_scale;
+                            p_vout->i_changes |= VOUT_SCALE_CHANGE;
+                            break;
+
+                        case ' ':                        /* toggle interface */
+                            p_vout->b_interface = ! p_vout->b_interface;
+                            p_vout->i_changes |= VOUT_INTF_CHANGE;
+                            break;
+
                         case '0': network_ChannelJoin( 0 ); break;
                         case '1': network_ChannelJoin( 1 ); break;
                         case '2': network_ChannelJoin( 2 ); bre
ak;
@@ -403,7 +437,7 @@
                     }
 
                 default:
-                    intf_WarnMsg( 3, "vout: WinDX vout_Manage WM Default %i",
+                    intf_WarnMsg( 4, "vout: vout_Manage WM Default %i",
                                   msg.message );
                 break;
             }
@@ -430,12 +464,29 @@
      */
     if( p_vout->i_changes & VOUT_SIZE_CHANGE )
     {
-        intf_WarnMsg( 3, "vout: WinDX vout_Manage Size Change" );
-        WinDXUpdateOverlay( p_vout );
+        intf_WarnMsg( 3, "vout: vout_Manage Size Change" );
+        DirectXUpdateOverlay( p_vout );
         p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
     }
 
     /*
+     * YUV Change 
+     */
+    if( p_vout->i_changes & VOUT_YUV_CHANGE )
+    {
+        p_vout->b_need_render = ! p_vout->b_need_render;
+        
+        /* Need to reopen display */
+        DirectXCloseSurface( p_vout );
+        if( DirectXCreateSurface( p_vout ) )
+        {
+          intf_ErrMsg( "error: can't reopen display after YUV
 change" );
+          return( 1 );
+        }
+        p_vout->i_changes &= ~VOUT_YUV_CHANGE;
+    }
+
+    /*
      * Fullscreen change
      */
     if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
@@ -463,7 +514,6 @@
         }
 
         SetWindowPlacement( p_vout->p_sys->hwnd, &window_placement );
-        /*WinDXUpdateOverlay( p_vout );*/
 
         p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
     }
@@ -472,7 +522,7 @@
      * Pointer change
      */
     if( ! p_vout->p_sys->b_cursor_autohidden &&
-        ( mdate() - p_vout->p_sys->i_lastmoved > 2000000 ) )
+        ( mdate() - p_vout->p_sys->i_lastmoved > 5000000 ) )
     {
         /* Hide the mouse automatically */
         p_vout->p_sys->b_cursor_autohidden = 1;
@@ -521,6 +571,8 @@
     int           i_image_height = p_vout->p_rendered_pic->i_height;
 
 
+    intf_WarnMsg( 5, "vout: vout_Display" );
+
     if( (p_vout->p_sys->p_display == NULL) )
     {
         intf_WarnMsg( 3, "vout error: WinDX no display!!" );
@@ -530,9 +582,66 @@
     /* T
he first time this function is called it enables the display */
     p_vout->p_sys->b_display_enabled = 1;
 
+    /* if the size of the decoded pictures has changed then we close the
+     * video surface (which doesn't have the right size anymore). */
+    if( p_vout->p_sys->i_image_width != i_image_width
+        || p_vout->p_sys->i_image_height != i_image_height )
+    {
+        intf_WarnMsg( 3, "vout: video surface size changed" );
+        p_vout->p_sys->i_image_width = i_image_width;
+        p_vout->p_sys->i_image_height = i_image_height;
+        DirectXCloseSurface( p_vout );
+    }
+
     if( p_vout->b_need_render )
     {
+        RECT  rect_window;
+        POINT point_window;
+  
         /* Nothing yet */
+        if( p_vout->p_sys->p_surface == NULL )
+        {
+            intf_WarnMsg( 3, "vout: no video surface, open one..." );
+            if( DirectXCreateSurface( p_vout ) )
+            {
+                intf_WarnMsg( 3, "vout: cannot open a new video surface !!" );
+                re
turn;
+            }
+            /* Display the surface */
+            p_vout->p_sys->b_display_enabled = 1;
+        }
+
+        /* Now get the coordinates of the window. We don't actually want the
+         * window coordinates but these of the usable surface inside the window
+         * By specification GetClientRect will always set rect_window.left and
+         * rect_window.top to 0 because the Client area is always relative to
+         * the container window */
+        GetClientRect(p_vout->p_sys->hwnd, &rect_window);
+        
+        point_window.x = 0;
+        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;
+
+        /* Blit
 video surface to display */
+        dxresult = IDirectDrawSurface3_Blt(p_vout->p_sys->p_surface,
+                                           NULL,
+                                           p_vout->p_sys->p_display,
+                                           &rect_window,
+                                           0, NULL );
+        if( dxresult != DD_OK )
+        {
+            intf_WarnMsg( 3, "vout: could not Blit the surface" );
+            return;
+        }
+
     }
     else
     {
@@ -542,47 +651,36 @@
          */
         /* TODO: support for streams other than 4:2:0 */
 
-        /* if the size of the decoded pictures has changed then we close the
-         * YUVOverlay (which doesn't have the right size anymore). */
-        if( p_vout->p_sys->i_image_width != i_image_width
-            || p_vout->p_sys->i_image_height != i_image_height )
+        if( p_vout->p_sys->p_surface == NULL )
         {
-            intf_WarnMsg( 3, "vout: WinDX overlay size changed" );
-            p_vout->p_sys
->i_image_width = i_image_width;
-            p_vout->p_sys->i_image_height = i_image_height;
-            WinDXCloseYUVOverlay( p_vout );
-        }
-
-        if( p_vout->p_sys->p_overlay == NULL )
-        {
-            intf_WarnMsg( 3, "vout: WinDX no overlay, open one..." );
-            if( WinDXCreateYUVOverlay( p_vout ) )
+            intf_WarnMsg( 3, "vout: no video surface, open one..." );
+            if( DirectXCreateSurface( p_vout ) )
             {
-                intf_WarnMsg( 3, "vout: WinDX cannot open a new overlay !!" );
+                intf_WarnMsg( 3, "vout: cannot open a new video surface !!" );
                 return;
             }
             /* Display the Overlay */
             p_vout->p_sys->b_display_enabled = 1;
-            WinDXUpdateOverlay( p_vout );
+            DirectXUpdateOverlay( p_vout );
         }
 
         /* Lock the overlay surface */
         memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
         ddsd.dwSize = sizeof(DDSURFACEDESC);
-        dxresult = IDire
ctDrawSurface_Lock(p_vout->p_sys->p_overlay, NULL,
-                                           &ddsd, DDLOCK_NOSYSLOCK, NULL);
+        dxresult = IDirectDrawSurface3_Lock(p_vout->p_sys->p_surface, NULL,
+                                            &ddsd, DDLOCK_NOSYSLOCK, NULL);
         if ( dxresult == DDERR_SURFACELOST )
         {
             /* Your surface can be lost (thanks to windows) so be sure
              * to check this and restore it if needed */
-            dxresult = IDirectDrawSurface_Restore( p_vout->p_sys->p_overlay );
-            dxresult = IDirectDrawSurface_Lock( p_vout->p_sys->p_overlay,
-                                                NULL, &ddsd, DDLOCK_NOSYSLOCK
-                                                | DDLOCK_WAIT, NULL);
+            dxresult = IDirectDrawSurface3_Restore( p_vout->p_sys->p_surface );
+            dxresult = IDirectDrawSurface3_Lock( p_vout->p_sys->p_surface,
+                                                 NULL, &ddsd, DDLOCK_NOSYSLOCK
+             
                                    | DDLOCK_WAIT, NULL);
         }
         if( dxresult != DD_OK )
         {
-            intf_WarnMsg( 3, "vout: WinDX could not lock the surface" );
+            intf_WarnMsg( 3, "vout: could not lock the surface" );
             return;
         }
 
@@ -634,8 +732,8 @@
         }
 
         /* Unlock the Surface */
-        dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_overlay,
-                                             ddsd.lpSurface );
+        dxresult = IDirectDrawSurface3_Unlock(p_vout->p_sys->p_surface,
+                                              ddsd.lpSurface );
 
     }
 
@@ -646,7 +744,7 @@
 
 
 /*****************************************************************************
- * WinDXEventProc: This is the window event processing function.
+ * DirectXEventProc: This is the window event processing function.
  *****************************************************************************
  * On Windows, when you create a window you have to attach an ev
ent processing
  * function to it. The aim of this function is to manage "Queued Messages" and
@@ -656,28 +754,28 @@
  * Nonqueued Messages are those that Windows will send directly to this
  * function (like WM_DESTROY, WM_WINDOWPOSCHANGED...)
  *****************************************************************************/
-long FAR PASCAL WinDXEventProc( HWND hwnd, UINT message,
-                                WPARAM wParam, LPARAM lParam )
+long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
+                                  WPARAM wParam, LPARAM lParam )
 {
     switch( message )
     {
 
     case WM_ACTIVATE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_ACTIVED" );
+        intf_WarnMsg( 4, "vout: WinProc WM_ACTIVED" );
         break;
 
     case WM_CREATE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_CREATE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_CREATE" );
         break;
 
     /* the user wants to close the window */
     case WM_CLOSE:
-        intf_WarnMsg( 3, "vout: Wi
nDX WinProc WM_CLOSE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_CLOSE" );
         break;
 
     /* the window has been closed so shut down everything now */
     case WM_DESTROY:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_DESTROY" );
+        intf_WarnMsg( 4, "vout: WinProc WM_DESTROY" );
         PostQuitMessage( 0 );
         break;
 
@@ -686,46 +784,46 @@
         {
             case SC_SCREENSAVE:                     /* catch the screensaver */
             case SC_MONITORPOWER:              /* catch the monitor turn-off */
-            intf_WarnMsg( 3, "vout: WinDX WinProc WM_SYSCOMMAND" );
+            intf_WarnMsg( 3, "vout: WinProc WM_SYSCOMMAND" );
             return 0;                      /* this stops them from happening */
         }
         break;
 
     case WM_MOVE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVE" );
+        intf_WarnMsg( 4, "vout: WinProc WM_MOVE" );
         break;
 
     case WM_SIZE:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_SIZE" );
+       
 intf_WarnMsg( 4, "vout: WinProc WM_SIZE" );
         break;
 
     case WM_MOVING:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_MOVING" );
+        intf_WarnMsg( 4, "vout: WinProc WM_MOVING" );
         break;
 
     case WM_SIZING:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_SIZING" );
+        intf_WarnMsg( 4, "vout: WinProc WM_SIZING" );
         break;
 
     case WM_WINDOWPOSCHANGED:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_WINDOWPOSCHANGED" );
+        intf_WarnMsg( 3, "vout: WinProc WM_WINDOWPOSCHANGED" );
         PostMessage( NULL, WM_APP, 0, 0);
         break;
 
     case WM_WINDOWPOSCHANGING:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_WINDOWPOSCHANGING" );
+        intf_WarnMsg( 3, "vout: WinProc WM_WINDOWPOSCHANGING" );
         break;
 
     case WM_PAINT:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_PAINT" );
+        intf_WarnMsg( 4, "vout: WinProc WM_PAINT" );
         break;
 
     case WM_ERASEBKGND:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM_ERASEBKG
ND" );
+        intf_WarnMsg( 4, "vout: WinProc WM_ERASEBKGND" );
         break;
 
     default:
-        intf_WarnMsg( 3, "vout: WinDX WinProc WM Default %i", message );
+        intf_WarnMsg( 4, "vout: WinProc WM Default %i", message );
         break;
     }
 
@@ -733,13 +831,13 @@
 }
 
 /*****************************************************************************
- * WinDXCreateWindow: create a windows window where the video will play.
+ * DirectXCreateWindow: create a windows window where the video will play.
  *****************************************************************************
  * Before creating a direct draw surface, we need to create a window in which
  * the video will be displayed. This window will also allow us to capture the
  * events.
  *****************************************************************************/
-static int WinDXCreateWindow( vout_thread_t *p_vout )
+static int DirectXCreateWindow( vout_thread_t *p_vout )
 {
     HINSTANCE hInstance;
     WNDCLASS  wc;            
                     /* window class components */
@@ -770,7 +868,7 @@
         if( colorkey == GetNearestColor( hdc, colorkey ) )
           break;
     }
-    intf_WarnMsg( 3, "vout: WinDXCreateWindow background color:%i", colorkey );
+    intf_WarnMsg(3,"vout: DirectXCreateWindow background color:%i", colorkey);
     ReleaseDC( p_vout->p_sys->hwnd, hdc );
 
     /* create the actual brush */  
@@ -779,7 +877,7 @@
 
     /* fill in the window class structure */
     wc.style         = 0;                               /* no special styles */
-    wc.lpfnWndProc   = (WNDPROC)WinDXEventProc;             /* event handler */
+    wc.lpfnWndProc   = (WNDPROC)DirectXEventProc;           /* event handler */
     wc.cbClsExtra    = 0;                             /* no extra class data */
     wc.cbWndExtra    = 0;                            /* no extra window data */
     wc.hInstance     = hInstance;                                /* instance */
@@ -791,7 +889,7 @@
 
     /* register the window class */
     if (!R
egisterClass(&wc)) {
-        intf_WarnMsg( 3, "vout: WinDX register window FAILED" );
+        intf_WarnMsg( 3, "vout: DirectXCreateWindow register window FAILED" );
         return (1);
     }
 
@@ -820,7 +918,7 @@
                     NULL);                        /* no additional arguments */
 
     if (p_vout->p_sys->hwnd == NULL) {
-        intf_WarnMsg( 3, "vout: WinDX create window FAILED" );
+        intf_WarnMsg( 3, "vout: DirectXCreateWindow create window FAILED" );
         return (1);
     }
 
@@ -831,72 +929,106 @@
 }
 
 /*****************************************************************************
- * WinDXInitDDraw: Takes care of all the DirectDraw initialisations
+ * DirectXInitDDraw: Takes care of all the DirectDraw initialisations
  *****************************************************************************
  * This function initialise and allocate resources for DirectDraw.
  *****************************************************************************/
-static int WinDXInitDDraw( vout_th
read_t *p_vout )
+static int DirectXInitDDraw( vout_thread_t *p_vout )
 {
-    HRESULT     dxresult;
-    DWORD       flags;
+    HRESULT    dxresult;
+    HRESULT    (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
+    LPDIRECTDRAW  p_ddobject;
 
-    intf_WarnMsg( 3, "vout: WinDX WinDXInitDDraw" );
+    intf_WarnMsg( 3, "vout: DirectXInitDDraw" );
 
-    /* Initialize DirectDraw */
-    dxresult = DirectDrawCreate( NULL, &p_vout->p_sys->p_ddobject, NULL );
-    if( dxresult != DD_OK )
+    /* load direct draw DLL */
+    p_vout->p_sys->hddraw_dll = LoadLibrary("DDRAW.DLL");
+    if( p_vout->p_sys->hddraw_dll == NULL )
     {
-        intf_ErrMsg( "vout error: can't initialize Direct Draw" );
+        intf_WarnMsg( 3, "vout: DirectXInitDDraw failed loading ddraw.dll" );
         return( 1 );
     }
+      
+    OurDirectDrawCreate = 
+      (void *)GetProcAddress(p_vout->p_sys->hddraw_dll, "DirectDrawCreate");
+    if ( OurDirectDrawCreate == NULL )
+    {
+        intf_ErrMsg( "vout error: 
DirectXInitDDraw failed GetProcAddress" );
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+        return( 1 );    
+    }
 
-    /* Set DirectDraw Cooperative level, ie what control we want over Windows
-       display */
-    if( p_vout->b_fullscreen )
+    /* Initialize DirectDraw now */
+    dxresult = OurDirectDrawCreate( NULL, &p_ddobject, NULL );
+    if( dxresult != DD_OK )
     {
-        flags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
+        intf_ErrMsg( "vout error: DirectXInitDDraw can't initialize DDraw" );
+        p_vout->p_sys->p_ddobject = NULL;
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+        return( 1 );
     }
-    else
+
+    /* Set DirectDraw Cooperative level, ie what control we want over Windows
+     * display */
+    dxresult = IDirectDraw_SetCooperativeLevel( p_ddobject,
+                                           p_vout->p_sys->hwnd, DDSCL_NORMAL );
+    if( dxresult != DD_OK )
     {

-        flags = DDSCL_NORMAL;
+        intf_ErrMsg( "vout error: can't set direct draw cooperative level." );
+        IDirectDraw_Release( p_ddobject );
+        p_vout->p_sys->p_ddobject = NULL;
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+        return( 1 );
     }
 
-    dxresult = IDirectDraw_SetCooperativeLevel( p_vout->p_sys->p_ddobject,
-                                                p_vout->p_sys->hwnd, flags );
+    /* Get the IDirectDraw2 interface */
+    dxresult = IDirectDraw_QueryInterface( p_ddobject, &IID_IDirectDraw2,
+                                        (LPVOID *)&p_vout->p_sys->p_ddobject );
     if( dxresult != DD_OK )
     {
-        intf_ErrMsg( "vout error: can't set direct draw cooperative level." );
-        IDirectDraw_Release(p_vout->p_sys->p_ddobject);
+        intf_ErrMsg( "vout error: can't get IDirectDraw2 interface." );
+        IDirectDraw_Release( p_ddobject );
         p_vout->p_sys->p_ddobject = NULL;
+        FreeL
ibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
         return( 1 );
     }
+    else
+    {
+        /* Release the unused interface */
+        IDirectDraw_Release( p_ddobject );
+    }
 
     return( 0 );
 }
 
 /*****************************************************************************
- * WinDXCreateDisplay: create the DirectDraw display.
+ * DirectXCreateDisplay: create the DirectDraw display.
  *****************************************************************************
  * Create and initialize display according to preferences specified in the vout
  * thread fields.
  *****************************************************************************/
-static int WinDXCreateDisplay( vout_thread_t *p_vout )
+static int DirectXCreateDisplay( vout_thread_t *p_vout )
 {
-    DDCAPS        ddcaps;
-    HRESULT       dxresult;
-    DDSURFACEDESC ddsd;
-    BOOL          bHasOverlay, bHasColorKey, bCanStretch;
+    HRESULT              dxresult;
+    DDSURFACEDESC        ddsd;
+    LPDIRECTDRAWSURFACE  p_display;
 
-    /* Now create the primary surface. This surface is the displayed surface */
-    /* The following two steps are important! */
+    intf_WarnMsg( 3, "vout: DirectXCreateDisplay" );
+
+    /* Now create the primary surface. This surface is what you actually see
+     * on your screen */
     memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
     ddsd.dwSize = sizeof(DDSURFACEDESC);
     ddsd.dwFlags = DDSD_CAPS;
     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 
-    dxresult = IDirectDraw_CreateSurface( p_vout->p_sys->p_ddobject,
-                                          &ddsd,
-                                          &p_vout->p_sys->p_display, NULL );
+    dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
+                                           &ddsd,
+                                           &p_display, NULL );
     if( dxresult != DD_OK )
     {
         intf_ErrMsg( "vout error: can't create direct draw primary surface." );
@@ -904,57 +1036,7
4 @@
         return( 1 );
     }
 
-#if 0
-    /* Now create a clipper for our window.
-     * This clipper prevents us to modify by mistake anything on the screen
-     * (primary surface) which doesn't belong to our window */
-    dxresult = IDirectDraw_CreateClipper(p_vout->p_sys->p_ddobject, 0,
-                                         &p_vout->p_sys->p_clipper, NULL);
-    if( dxresult != DD_OK )
+    dxresult = IDirectDrawSurface_QueryInterface( p_display,
+                                         &IID_IDirectDrawSurface3,
+                                         (LPVOID *)&p_vout->p_sys->p_display );
+    if ( dxresult != DD_OK )
     {
-        intf_ErrMsg( "vout error: can't create clipper." );
-        IDirectDrawSurface_Release( p_vout->p_sys->p_display );
+        intf_ErrMsg( "vout error: can't get IDirectDrawSurface3 interface." );
+        IDirectDrawSurface_Release( p_display );
         p_vout->p_sys->p_display = NULL;
         return( 1 );
     }
-
-    dxresult = IDirectDrawClipper_SetHWn
d(p_vout->p_sys->p_clipper, 0,
-                                              p_vout->p_sys->hwnd);
-    if( dxresult != DD_OK )
+    else
     {
-        intf_ErrMsg( "vout error: can't attach clipper to window." );
-        IDirectDrawSurface_Release( p_vout->p_sys->p_display );
-        p_vout->p_sys->p_display = NULL;
-        return( 1 );
+        /* Release the old interface */
+        IDirectDrawSurface_Release( p_display );
     }
 
-    dxresult = IDirectDrawSurface_SetClipper(p_vout->p_sys->p_display,
-                                              p_vout->p_sys->p_clipper);
-    if( dxresult != DD_OK )
+
+    /* Create a video surface. This function will try to create an
+     * YUV overlay first and if it can't it will create a simple RGB surface */
+    if( DirectXCreateSurface( p_vout ) )
     {
-        intf_ErrMsg( "vout error: can't attach clipper to surface." );
-        IDirectDrawSurface_Release( p_vout->p_sys->p_display );
+        intf_ErrMsg( "vout error: can't create a video surface." 
);
+        IDirectDrawSurface3_Release( p_vout->p_sys->p_display );
         p_vout->p_sys->p_display = NULL;
         return( 1 );
     }
-#endif
+      
+    return( 0 );
+}
+
+/*****************************************************************************
+ * DirectXCreateSurface: create an YUV overlay or RGB surface for the video.
+ *****************************************************************************
+ * The best method of display is with an YUV overlay because the YUV->RGB
+ * conversion is done in hardware, so we'll try to create this surface first.
+ * If we fail, we'll try to create a plain RGB surface.
+ * ( Maybe we could also try an RGB overlay surface, which could have hardware
+ * scaling and which would also be faster in window mode because you don't
+ * need to do any blitting to the main display...)
+ *****************************************************************************/
+static int DirectXCreateSurface( vout_thread_t *p_vout )
+{
+    HRESULT dxresult;
+    DDSURFACEDESC ddsd
;
+    LPDIRECTDRAWSURFACE p_surface;
+    DDCAPS ddcaps;
 
+    intf_WarnMsg( 3, "vout: DirectXCreateSurface" );
+
+    /* Disable display */
+    p_vout->p_sys->b_display_enabled = 0;
+
+#if 1
     /* 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 whether or not we'll support overlay,
      * but with this test we don't know if we support YUV overlay */
     memset( &ddcaps, 0, sizeof( DDCAPS ));
     ddcaps.dwSize = sizeof(DDCAPS);
-    dxresult = IDirectDraw_GetCaps( p_vout->p_sys->p_ddobject,
-                                    &ddcaps, NULL );
+    dxresult = IDirectDraw2_GetCaps( p_vout->p_sys->p_ddobject,
+                                     &ddcaps, NULL );
     if(dxresult != DD_OK )
     {
-        intf_ErrMsg( "vout error: can't get caps." );
-        bHasOverlay  = FALSE;
-        bHasColorKey = FALSE;
-        bCanStretch  = FALSE;
+        intf_WarnMsg( 3,"vout error: can't get caps." )
;
     }
     else
     {
+        BOOL bHasOverlay, bHasColorKey, bCanStretch;
+
         /* Determine if the hardware supports overlay surfaces */
         bHasOverlay = ((ddcaps.dwCaps & DDCAPS_OVERLAY) ==
                        DDCAPS_OVERLAY) ? TRUE : FALSE;
@@ -964,59 +1113,154 @@
         /* Determine if the hardware supports scaling of the overlay surface */
         bCanStretch = ((ddcaps.dwCaps & DDCAPS_OVERLAYSTRETCH) ==
                        DDCAPS_OVERLAYSTRETCH) ? TRUE : FALSE;
-        intf_WarnMsg( 3, "vout: WinDX Caps: overlay=%i colorkey=%i stretch=%i",
+        intf_WarnMsg( 3, "vout: Dx Caps: overlay=%i colorkey=%i stretch=%i",
                          bHasOverlay, bHasColorKey, bCanStretch );
+
+        if( !bHasOverlay ) p_vout->b_need_render = 1;
     }
+#endif
 
-    p_vout->p_sys->p_overlay = NULL;
-    if( bHasOverlay && bHasColorKey && bCanStretch )
+
+    /* Create the video surface */
+    if( !p_vout->b_need_render )
     {
-        if( !WinDXCreateYUVOverlay( p_vout ) )
+   
     /* Now try to create the YUV overlay surface.
+         * This overlay will be displayed on top of the primary surface.
+         * 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
+         * surface wherever the primary surface will have this color.
+         * The video window has been created with a background of this color so
+         * the overlay will be only displayed on top of this window */
+
+        memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
+        ddsd.dwSize = sizeof(DDSURFACEDESC);
+        ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
+        ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
+        ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2');
+#ifdef NONAMELESSUNION
+        ddsd.ddpfPixelFormat.u1.dwYUVBitCount = 16;
+#else
+        ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
+#endif
+        ddsd.dwFlags = DDSD_CAPS |
+                       DDSD_HEIGHT |
+            
           DDSD_WIDTH |
+                       DDSD_PIXELFORMAT;
+        ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
+        ddsd.dwHeight =  p_vout->p_sys->i_image_height;
+        ddsd.dwWidth =  p_vout->p_sys->i_image_width;
+
+        dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
+                                               &ddsd, &p_surface, NULL );
+        if( dxresult == DD_OK )
         {
-           /* Overlay created successfully */
-           p_vout->b_need_render = 0;
+            intf_WarnMsg( 3,"vout: DirectX YUV overlay created successfully" );
         }
+        else
+        {
+            intf_ErrMsg( "vout error: can't create YUV overlay surface." );
+            p_vout->b_need_render = 1;
+        }
     }
 
-
-    /* Now do some initialisation for video_output */
     if( p_vout->b_need_render )
     {
-        /* if we want a valid pointer to the surface memory, we must lock
-         * the surface */
+        /* Now try to create a plain RGB
 surface. */
         memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
         ddsd.dwSize = sizeof(DDSURFACEDESC);
-        dxresult = IDirectDrawSurface_Lock(p_vout->p_sys->p_display,
-                                           NULL, &ddsd,
-                                           DDLOCK_NOSYSLOCK, NULL);
-        if ( dxresult == DDERR_SURFACELOST )
+        ddsd.dwFlags = DDSD_HEIGHT |
+                       DDSD_WIDTH |
+                       DDSD_CAPS;
+        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+        ddsd.dwHeight =  p_vout->p_sys->i_image_height;
+        ddsd.dwWidth =  p_vout->p_sys->i_image_width;
+
+        dxresult = IDirectDraw2_CreateSurface( p_vout->p_sys->p_ddobject,
+                                               &ddsd, &p_surface, NULL );
+        if( dxresult == DD_OK )
         {
-            /* Your surface can be lost so be sure
-             * to check this and restore it if needed */
-            dxresult = IDirectDrawSurface_Restore( p_vout->p_sys->p_display );
-      
      dxresult = IDirectDrawSurface_Lock( p_vout->p_sys->p_display,
-                                                NULL, &ddsd, DDLOCK_NOSYSLOCK
-                                                | DDLOCK_WAIT, NULL);
+            intf_WarnMsg( 3,"vout: DirectX RGB surface created successfully" );
         }
-        if( dxresult != DD_OK )
+        else
         {
-            intf_WarnMsg( 3, "vout: WinDX could not lock the surface" );
+            intf_ErrMsg( "vout error: can't create RGB surface." );
+            p_vout->p_sys->p_surface = NULL;
             return( 1 );
         }
+    }
+      
+    /* Now that the surface is created, try to get a newer DirectX interface */
+    dxresult = IDirectDrawSurface_QueryInterface( p_surface,
+                                         &IID_IDirectDrawSurface3,
+                                         (LPVOID *)&p_vout->p_sys->p_surface );
+    if ( dxresult != DD_OK )
+    {
+        intf_ErrMsg( "vout error: can't get IDirectDrawSurface3 interface." );
+     
   IDirectDrawSurface_Release( p_surface );
+        p_vout->p_sys->p_surface = NULL;
+        return( 1 );
+    }
+    else
+    {
+        /* Release the old interface */
+        IDirectDrawSurface_Release( p_surface );
+    }
 
-        /* Set the pointer to the surface memory */
-        p_vout->p_sys->p_windx_buf[ 0 ] = ddsd.lpSurface;
-        /* back buffer, none for now */
-        p_vout->p_sys->p_windx_buf[ 1 ] = ddsd.lpSurface;
+    if( p_vout->b_need_render )
+    {
+        /* Hide the overlay for now */
+        IDirectDrawSurface3_UpdateOverlay(p_vout->p_sys->p_surface,
+                                          NULL,
+                                          p_vout->p_sys->p_display,
+                                          NULL,
+                                          DDOVER_HIDE,
+                                          NULL);
+    }
+
 
+    /* From now on, do some initialisation for video_output */
 
-        /* Set thread information */
-        p_vout->i_width =           ddsd.d
wWidth;
-        p_vout->i_height =          ddsd.dwHeight;
+    /* if we want a valid pointer to the surface memory, we must lock
+     * the surface */
 
+    memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
+    ddsd.dwSize = sizeof(DDSURFACEDESC);
+    dxresult = IDirectDrawSurface3_Lock( p_vout->p_sys->p_surface, NULL, &ddsd,
+                                         DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
+    if ( dxresult == DDERR_SURFACELOST )
+    {
+        /* Your surface can be lost so be sure
+         * to check this and restore it if needed */
+        dxresult = IDirectDrawSurface3_Restore( p_vout->p_sys->p_surface );
+        dxresult = IDirectDrawSurface3_Lock( p_vout->p_sys->p_surface,
+                                             NULL, &ddsd, DDLOCK_NOSYSLOCK
+                                             | DDLOCK_WAIT, NULL);
+    }
+    if( dxresult != DD_OK )
+    {
+        intf_ErrMsg( "vout: DirectXCreateDisplay could not lock the surface" );
+        return( 1 );
+    }
+
+    /* Set the 
pointer to the surface memory */
+    p_vout->p_sys->p_directx_buf[ 0 ] = ddsd.lpSurface;
+    /* back buffer, none for now */
+    p_vout->p_sys->p_directx_buf[ 1 ] = ddsd.lpSurface;
+
+    /* Set thread information */
+    p_vout->i_width =  ddsd.dwWidth;
+    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 */
+
 
+    if( p_vout->b_need_render )
+    {
+        /* For an RGB surface we need to fill in some more info */
+#ifdef NONAMELESSUNION
         p_vout->i_screen_depth =    ddsd.ddpfPixelFormat.u1.dwRGBBitCount;
         p_vout->i_bytes_per_pixel = ddsd.ddpfPixelFormat.u1.dwRGBBitCount/8;
 
@@ -1024,8 +1268,6 @@
         p_vout->i_green_mask =      ddsd.ddpfPixelFormat.u3.dwGBitMask;
         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;
 
@@ -1034,144 +1276,42 @@
         p_vout->i_blue_mask =       ddsd.ddpfPixelFormat.dwBBitMask;
 
 #endif /* NONAMELESSUNION */
-
-        /* Unlock the Surface */
-        dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_display,
-                                             ddsd.lpSurface );
-        /* FIXME: palette in 8bpp ?? */
-        /* Set and initialize buffers */
-        p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_windx_buf[ 0 ],
-                                 p_vout->p_sys->p_windx_buf[ 1 ] );
-    }
-    else
-    {
-        /* Lock the surface */
-        memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
-        ddsd.dwSize = sizeof(DDSURFACEDESC);
-        dxresult = IDirectDrawSurface_Lock(p_vout->p_sys->p_overlay,
-                                          NULL, &ddsd, DDLOCK_NOSYSLOCK, NULL);
-        if ( dxresult == DDERR_SURFACELOST
 )
-        {
-            /* Your surface can be lost (thanks to windows) so be sure
-             * to check this every time you want to do something with
-             * it */
-            dxresult = IDirectDrawSurface_Restore(
-                                           p_vout->p_sys->p_overlay );
-            dxresult = IDirectDrawSurface_Lock( p_vout->p_sys->p_overlay
-                        , NULL, &ddsd,DDLOCK_NOSYSLOCK| DDLOCK_WAIT, NULL);
-        }
-        if( dxresult != DD_OK )
-        {
-            intf_WarnMsg( 3, "vout: WinDX could not lock the surface" );
-            return( 1 );
-        }
-
-        p_vout->p_sys->p_windx_buf[ 0 ] = ddsd.lpSurface;
-        p_vout->p_sys->p_windx_buf[ 1 ] = ddsd.lpSurface;
-
-        /* Set thread information */
-        p_vout->i_width =           ddsd.dwWidth;
-        p_vout->i_height =          ddsd.dwHeight;
-#ifdef NONAMELESSUNION
-        p_vout->i_bytes_per_line =  ddsd.u1.lPitch;
-#else
-        p_vout->i_bytes_per_line =  ddsd.lPitch;
-#endif
 /* NONAMELESSUNION */
-
-        /* Unlock the Surface */
-        dxresult = IDirectDrawSurface_Unlock(p_vout->p_sys->p_overlay,
-                                             ddsd.lpSurface );
-
-        p_vout->pf_setbuffers( p_vout, p_vout->p_sys->p_windx_buf[ 0 ],
-                                 p_vout->p_sys->p_windx_buf[ 1 ] );
     }
 
-    return( 0 );
-}
-
-/*****************************************************************************
- * WinDXCreateYUVOveraly: create an YUV overlay surface for the video.
- *****************************************************************************
- * The best method of display is with an YUV overlay because the YUV->RGB
- * conversion is done in hardware.
- * This function will try to create an YUV overlay.
- *****************************************************************************/
-static int WinDXCreateYUVOverlay( vout_thread_t *p_vout )
-{
-    HRESULT dxresult;
-    DDSURFACEDESC ddsd;
-
-    /* Now create the overlay surface. This overlay will be dis
played on
-     * top of the primary surface.
-     * 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
-     * surface wherever the primary surface will have this color.
-     * The video window has been created with a background of this color so
-     * the overlay will be only displayed on top of this window */
-
-    memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
-    ddsd.dwSize = sizeof(DDSURFACEDESC);
-    ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
-    ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
-    ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC('Y','V','1','2');
-#ifdef NONAMELESSUNION
-    ddsd.ddpfPixelFormat.u1.dwYUVBitCount = 16;
-#else
-    ddsd.ddpfPixelFormat.dwYUVBitCount = 16;
-#endif
+    /* Unlock the Surface */
+    dxresult = IDirectDrawSurface3_Unlock(p_vout->p_sys->p_surface,
+                                          ddsd.lpSurface );
+
+    /* Set and initialize buffers */
+    p_vout->p
f_setbuffers( p_vout, p_vout->p_sys->p_directx_buf[ 0 ],
+                           p_vout->p_sys->p_directx_buf[ 1 ] );
 
-    ddsd.dwSize = sizeof(DDSURFACEDESC);
-    ddsd.dwFlags = DDSD_CAPS |
-                   DDSD_HEIGHT |
-                   DDSD_WIDTH |
-                   DDSD_PIXELFORMAT;
-    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
-    ddsd.dwHeight =  p_vout->p_sys->i_image_height;
-    ddsd.dwWidth =  p_vout->p_sys->i_image_width;
-
-    dxresult = IDirectDraw_CreateSurface( p_vout->p_sys->p_ddobject,
-                                          &ddsd,
-                                          &p_vout->p_sys->p_overlay, NULL );
-    if( dxresult != DD_OK )
-    {
-        intf_ErrMsg( "vout error: can't create overlay surface." );
-        p_vout->p_sys->p_overlay = NULL;
-    }
-    else
-    {
-        intf_WarnMsg( 3, "vout: WinDX YUV overlay created successfully" );
-    }
-    /* Hide the overlay for now */
-    IDirectDrawSurface_UpdateOverlay(p_vout->p_sys->p_overla
y,
-                                     NULL,
-                                     p_vout->p_sys->p_display,
-                                     NULL,
-                                     DDOVER_HIDE,
-                                     NULL);
 
     return ( 0 );
 }
 
+
 /*****************************************************************************
- * WinDXUpdateOverlay: Move or resize overlay surface on video display.
+ * DirectXUpdateOverlay: Move or resize overlay surface on video display.
  *****************************************************************************
  * 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
  * event (in vout_Manage).
  *****************************************************************************/
-static int WinDXUpdateOverlay( vout_thread_t *p_vout )
+static int DirectXUpdateOverlay( vout_thread_t *p_vout )
 {
     DDOVERLAYFX     ddofx;
-    RECT            rect_win
dow, rect_image;
+    RECT            rect_window, rect_window_backup, rect_image;
     POINT           point_window;
     DWORD           dwFlags;
     HRESULT         dxresult;
     DWORD           dw_colorkey;
     DDPIXELFORMAT   pixel_format;
+    DDSURFACEDESC   ddsd;
 
-    if( p_vout->p_sys->p_overlay == NULL || p_vout->b_need_render)
+    if( p_vout->p_sys->p_surface == NULL || p_vout->b_need_render )
     {
-        intf_WarnMsg( 3, "vout: WinDX no overlay !!" );
+        intf_WarnMsg( 3, "vout: DirectXUpdateOverlay no overlay !!" );
         return( 0 );
     }
 
@@ -1292,16 +1432,65 @@
 
     /* It seems we can't feed the UpdateOverlay directdraw function with
      * negative values so we have to clip the computed rectangles */
-    /* FIXME */
+    memset( &ddsd, 0, sizeof( DDSURFACEDESC ));
+    ddsd.dwSize = sizeof(DDSURFACEDESC);
+    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
+    IDirectDraw2_GetDisplayMode( p_vout->p_sys->p_ddobject, &ddsd );
+
+    rect_window_backup = rect_window;
 
+    /
* Clip the destination window */
+    rect_window.left = (rect_window.left < 0) ? 0 : rect_window.left;
+    rect_window.right = (rect_window.right < 0) ? 0 : rect_window.right;
+    rect_window.top = (rect_window.top < 0) ? 0 : rect_window.top;
+    rect_window.bottom = (rect_window.bottom < 0) ? 0 : rect_window.bottom;
+
+    rect_window.left = (rect_window.left > ddsd.dwWidth) ? ddsd.dwWidth
+      : rect_window.left;
+    rect_window.right = (rect_window.right > ddsd.dwWidth) ? ddsd.dwWidth
+      : rect_window.right;
+    rect_window.top = (rect_window.top > ddsd.dwHeight) ? ddsd.dwHeight
+      : rect_window.top;
+    rect_window.bottom = (rect_window.bottom > ddsd.dwHeight) ? ddsd.dwHeight
+      : rect_window.bottom;
+
+    intf_WarnMsg( 3, "vout: DirectXUpdateOverlay window coords: %i,%i,%i,%i",
+                  rect_window.left, rect_window.top,
+                  rect_window.right, rect_window.bottom);
+
+    /* Clip the source image */
+    rect_image.left = ( rect_window.left == rect_window_bac
kup.left ) ? 0
+      : labs(rect_window_backup.left - rect_window.left) *
+      p_vout->p_rendered_pic->i_width /
+      (rect_window_backup.right - rect_window_backup.left);
+    rect_image.right = ( rect_window.right == rect_window_backup.right ) ?
+      p_vout->p_rendered_pic->i_width
+      : p_vout->p_rendered_pic->i_width -
+      labs(rect_window_backup.right - rect_window.right) *
+      p_vout->p_rendered_pic->i_width /
+      (rect_window_backup.right - rect_window_backup.left);
+    rect_image.top = ( rect_window.top == rect_window_backup.top ) ? 0
+      : labs(rect_window_backup.top - rect_window.top) *
+      p_vout->p_rendered_pic->i_height /
+      (rect_window_backup.bottom - rect_window_backup.top);
+    rect_image.bottom = ( rect_window.bottom == rect_window_backup.bottom ) ?
+      p_vout->p_rendered_pic->i_height
+      : p_vout->p_rendered_pic->i_height -
+      labs(rect_window_backup.bottom - rect_window.bottom) *
+      p_vout->p_rendered_pic->i_height /
+      (rect_window_backup.
bottom - rect_window_backup.top);
+
+    intf_WarnMsg( 3, "vout: DirectXUpdateOverlay image coords: %i,%i,%i,%i",
+                  rect_image.left, rect_image.top,
+                  rect_image.right, rect_image.bottom);
 
     /* 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 );
+    dxresult = IDirectDrawSurface3_GetPixelFormat( p_vout->p_sys->p_display,
+                                                   &pixel_format );
     if( dxresult != DD_OK )
-        intf_WarnMsg( 3, "vout: WinDX GetPixelFormat failed !!" );
+        intf_WarnMsg( 3, "vout: DirectXUpdateOverlay GetPixelFormat failed" );
     dw_colorkey = (DWORD)p_vout->p_sys->i_colorkey;
 #ifdef NONAMELESSUNION
     dw_colorkey = (DWORD)((( dw_colorkey * pixel_format.u2.dwRBitMask)
 / 255)
@@ -1319,34 +1508,35 @@
 
     dwFlags = DDOVER_KEYDESTOVERRIDE | DDOVER_SHOW;
 
-    dxresult = IDirectDrawSurface_UpdateOverlay(p_vout->p_sys->p_overlay,
-                                                NULL,    /*&rect_image,*/
-                                                p_vout->p_sys->p_display,
-                                                &rect_window,
-                                                dwFlags,
-                                                &ddofx);
+    dxresult = IDirectDrawSurface3_UpdateOverlay(p_vout->p_sys->p_surface,
+                                                 &rect_image,
+                                                 p_vout->p_sys->p_display,
+                                                 &rect_window,
+                                                 dwFlags,
+                                                 &ddofx);
     if(dxresult != DD_OK)
     {
-        intf_WarnMsg( 3, "vout: WinDX can't move or resize overlay" );
+        intf_WarnMsg( 3,
+ 
         "vout: DirectXUpdateOverlay can't move or resize overlay" );
     }
 
     return ( 0 );
 }
 
 /*****************************************************************************
- * WinDXCloseWindow: close the window created by WinDXCreateWindow
+ * DirectXCloseWindow: close the window created by DirectXCreateWindow
  *****************************************************************************
- * This function returns all resources allocated by WinDXCreateWindow.
+ * This function returns all resources allocated by DirectXCreateWindow.
  *****************************************************************************/
-static void WinDXCloseWindow( vout_thread_t *p_vout )
+static void DirectXCloseWindow( vout_thread_t *p_vout )
 {
     HINSTANCE hInstance;
 
-    intf_WarnMsg( 3, "vout: WinDXCloseWindow" );
-    if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE )
+    intf_WarnMsg( 3, "vout: DirectXCloseWindow" );
+    if( p_vout->p_sys->hwnd != NULL )
     {
         DestroyWindow( p_vout->p_sys->hwnd);
- 
       p_vout->p_sys->hwnd = INVALID_HANDLE_VALUE;
+        p_vout->p_sys->hwnd = NULL;
     }
 
     hInstance = GetModuleHandle(NULL);
@@ -1354,74 +1544,77 @@
                      hInstance );          /* handle to application instance */
 
     /* free window background brush */
-    if( p_vout->p_sys->hwnd != INVALID_HANDLE_VALUE )
+    if( p_vout->p_sys->hwnd != NULL )
     {
         DeleteObject( p_vout->p_sys->hbrush );
-        p_vout->p_sys->hbrush = INVALID_HANDLE_VALUE;
+        p_vout->p_sys->hbrush = NULL;
     }
 }
 
 /*****************************************************************************
- * WinDXCloseDDraw: Release the DDraw object allocated by WinDXInitDDraw
+ * DirectXCloseDDraw: Release the DDraw object allocated by DirectXInitDDraw
  *****************************************************************************
- * This function returns all resources allocated by WinDXInitDDraw.
+ * This function returns all resources allocated by DirectXInitDDraw.
  *******************************
**********************************************/
-static void WinDXCloseDDraw( vout_thread_t *p_vout )
+static void DirectXCloseDDraw( vout_thread_t *p_vout )
 {
-    intf_WarnMsg(3, "vout: WinDXCloseDDraw" );
+    intf_WarnMsg(3, "vout: DirectXCloseDDraw" );
     if( p_vout->p_sys->p_ddobject != NULL )
     {
-        IDirectDraw_Release(p_vout->p_sys->p_ddobject);
+        IDirectDraw2_Release(p_vout->p_sys->p_ddobject);
         p_vout->p_sys->p_ddobject = NULL;
     }
+
+    if( p_vout->p_sys->hddraw_dll != NULL )
+    {
+        FreeLibrary( p_vout->p_sys->hddraw_dll );
+        p_vout->p_sys->hddraw_dll = NULL;
+    }
 }
 
 /*****************************************************************************
- * WinDXCloseDisplay: close and reset DirectX device
+ * DirectXCloseDisplay: close and reset the DirectX display device
  *****************************************************************************
- * This function returns all resources allocated by WinDXCreateDisplay and
- * restore the original state
 of the device.
+ * This function returns all resources allocated by DirectXCreateDisplay.
  *****************************************************************************/
-static void WinDXCloseDisplay( vout_thread_t *p_vout )
+static void DirectXCloseDisplay( vout_thread_t *p_vout )
 {
-    intf_WarnMsg( 3, "vout: WinDXCloseDisplay" );
+    intf_WarnMsg( 3, "vout: DirectXCloseDisplay" );
     if( p_vout->p_sys->p_display != NULL )
     {
-        if( p_vout->p_sys->p_overlay != NULL )
-        {
-            intf_WarnMsg( 3, "vout: WinDXCloseDisplay overlay" );
-            IDirectDraw_Release( p_vout->p_sys->p_overlay );
-            p_vout->p_sys->p_overlay = NULL;
-        }
+        DirectXCloseSurface( p_vout );
 
-        if( p_vout->p_sys->p_clipper != NULL )
-        {
-            intf_WarnMsg( 3, "vout: WinDXCloseDisplay clipper" );
-            IDirectDraw_Release( p_vout->p_sys->p_clipper );
-            p_vout->p_sys->p_clipper = NULL;
-        }
-
-        intf_WarnMsg( 3, "vout: WinDXCloseDis
play display" );
-        IDirectDraw_Release( p_vout->p_sys->p_display );
+        intf_WarnMsg( 3, "vout: DirectXCloseDisplay display" );
+        IDirectDraw2_Release( p_vout->p_sys->p_display );
         p_vout->p_sys->p_display = NULL;
     }
 }
 
 /*****************************************************************************
- * WinDXCloseYUVOverlay: close the overlay surface
+ * DirectXCloseSurface: close the YUV overlay or RGB surface.
  *****************************************************************************
- * This function returns all resources allocated by the overlay surface.
+ * This function returns all resources allocated by the surface.
  * We also call this function when the decoded picture change its dimensions
  * (in that case we close the overlay surface and reopen another with the
  * right dimensions).
  *****************************************************************************/
-static void WinDXCloseYUVOverlay( vout_thread_t *p_vout )
+static void DirectXCloseSurface( vout_t
hread_t *p_vout )
 {
-    intf_WarnMsg( 3, "vout: WinDXCloseYUVOverlay" );
-    if( p_vout->p_sys->p_overlay != NULL )
+    intf_WarnMsg( 3, "vout: DirectXCloseSurface" );
+    if( p_vout->p_sys->p_surface != NULL )
     {
-        IDirectDraw_Release( p_vout->p_sys->p_overlay );
-        p_vout->p_sys->p_overlay = NULL;
+        intf_WarnMsg( 3, "vout: DirectXCloseSurface surface" );
+        IDirectDraw2_Release( p_vout->p_sys->p_surface );
+        p_vout->p_sys->p_surface = NULL;
     }
+
+    if( p_vout->p_sys->p_clipper != NULL )
+    {
+        intf_WarnMsg( 3, "vout: DirectXCloseSurface clipper" );
+        IDirectDraw2_Release( p_vout->p_sys->p_clipper );
+        p_vout->p_sys->p_clipper = NULL;
+    }
+
+    /* Disable any display */
     p_vout->p_sys->b_display_enabled = 0;
 }




More information about the vlc-devel mailing list