]> git.sesse.net Git - vlc/blobdiff - modules/video_output/msw/wingdi.c
Removed useless b_focus variable in msw.
[vlc] / modules / video_output / msw / wingdi.c
old mode 100755 (executable)
new mode 100644 (file)
index f969312..b40fda3
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * wingdi.c : Win32 / WinCE GDI video output plugin for vlc
  *****************************************************************************
- * Copyright (C) 2002 the VideoLAN team
- * $Id: wingdi.c 18074 2006-11-26 16:26:44Z zorglub $
+ * Copyright (C) 2002-2009 the VideoLAN team
+ * $Id$
  *
  * Authors: Gildas Bazin <gbazin@videolan.org>
  *          Samuel Hocevar <sam@zoy.org>
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
 #include <vlc_interface.h>
 #include <vlc_playlist.h>
 #include <vlc_vout.h>
 
+#include <windows.h>
+#include <tchar.h>
 #include <commctrl.h>
 
 #include "vout.h"
 
-#ifdef MODULE_NAME_IS_wingapi
-    typedef struct GXDisplayProperties {
-        DWORD cxWidth;
-        DWORD cyHeight;
-        long cbxPitch;
-        long cbyPitch;
-        long cBPP;
-        DWORD ffFormat;
-    } GXDisplayProperties;
-
-    typedef struct GXScreenRect {
-        DWORD dwTop;
-        DWORD dwLeft;
-        DWORD dwWidth;
-        DWORD dwHeight;
-    } GXScreenRect;
-
-#   define GX_FULLSCREEN    0x01
-#   define GX_NORMALKEYS    0x02
-#   define GX_LANDSCAPEKEYS 0x03
-
-#   ifndef kfLandscape
-#       define kfLandscape      0x8
-#       define kfPalette        0x10
-#       define kfDirect         0x20
-#       define kfDirect555      0x40
-#       define kfDirect565      0x80
-#       define kfDirect888      0x100
-#       define kfDirect444      0x200
-#       define kfDirectInverted 0x400
-#   endif
-#endif /* MODULE_NAME_IS_wingapi */
-
 #define MAX_DIRECTBUFFERS 10
 
-#ifdef UNDER_CE
-#ifndef WS_OVERLAPPEDWINDOW
-#   define WS_OVERLAPPEDWINDOW 0xcf0000
-#endif
-#ifndef WS_EX_NOPARENTNOTIFY
-#   define WS_EX_NOPARENTNOTIFY 4
-#endif
-#ifndef WS_EX_APPWINDOW
-#define WS_EX_APPWINDOW 0x40000
-#endif
-#define SetWindowLongPtr SetWindowLong
-#define GetWindowLongPtr GetWindowLong
-#define GWLP_USERDATA GWL_USERDATA
-#define AdjustWindowRect(a,b,c)
-#endif //UNDER_CE
-
 #ifndef WS_NONAVDONEBUTTON
 #define WS_NONAVDONEBUTTON 0
 #endif
@@ -116,35 +70,27 @@ static void SetPalette( vout_thread_t *, uint16_t *, uint16_t *, uint16_t * );
 
 static void InitBuffers        ( vout_thread_t * );
 
-#ifdef MODULE_NAME_IS_wingapi
-#   define GXOpenDisplay p_vout->p_sys->GXOpenDisplay
-#   define GXCloseDisplay p_vout->p_sys->GXCloseDisplay
-#   define GXBeginDraw p_vout->p_sys->GXBeginDraw
-#   define GXEndDraw p_vout->p_sys->GXEndDraw
-#   define GXGetDisplayProperties p_vout->p_sys->GXGetDisplayProperties
-#   define GXSuspend p_vout->p_sys->GXSuspend
-#   define GXResume p_vout->p_sys->GXResume
-#endif
+
 
 #define DX_POSITION_CHANGE 0x1000
 
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-vlc_module_begin();
-    set_category( CAT_VIDEO );
-    set_subcategory( SUBCAT_VIDEO_VOUT );
+vlc_module_begin ()
+    set_category( CAT_VIDEO )
+    set_subcategory( SUBCAT_VIDEO_VOUT )
 #ifdef MODULE_NAME_IS_wingapi
-    set_shortname( "Windows GAPI" );
-    set_description( _("Windows GAPI video output") );
-    set_capability( "video output", 20 );
+    set_shortname( "Windows GAPI" )
+    set_description( N_("Windows GAPI video output") )
+    set_capability( "video output", 20 )
 #else
-    set_shortname( "Windows GDI" );
-    set_description( _("Windows GDI video output") );
-    set_capability( "video output", 10 );
+    set_shortname( "Windows GDI" )
+    set_description( N_("Windows GDI video output") )
+    set_capability( "video output", 10 )
 #endif
-    set_callbacks( OpenVideo, CloseVideo );
-vlc_module_end();
+    set_callbacks( OpenVideo, CloseVideo )
+vlc_module_end ()
 
 /*****************************************************************************
  * OpenVideo: activate GDI video thread output method
@@ -152,11 +98,9 @@ vlc_module_end();
 static int OpenVideo ( vlc_object_t *p_this )
 {
     vout_thread_t * p_vout = (vout_thread_t *)p_this;
-    vlc_value_t val;
 
-    p_vout->p_sys = (vout_sys_t *)malloc( sizeof(vout_sys_t) );
+    p_vout->p_sys = (vout_sys_t *)calloc( 1, sizeof(vout_sys_t) );
     if( !p_vout->p_sys ) return VLC_ENOMEM;
-    memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
 
 #ifdef MODULE_NAME_IS_wingapi
     /* Load GAPI */
@@ -197,105 +141,22 @@ static int OpenVideo ( vlc_object_t *p_this )
     p_vout->p_sys->render_height = p_vout->render.i_height;
 #endif
 
-    p_vout->p_sys->p_event = (vlc_object_t *)
-        vlc_object_create( p_vout, VLC_OBJECT_GENERIC );
-    if( !p_vout->p_sys->p_event )
-    {
-        free( p_vout->p_sys );
-        return VLC_ENOMEM;
-    }
-
     p_vout->pf_init = Init;
     p_vout->pf_end = End;
     p_vout->pf_manage = Manage;
     p_vout->pf_render = Render;
+    p_vout->pf_control = Control;
 #ifdef MODULE_NAME_IS_wingapi
     p_vout->pf_display = FirstDisplayGAPI;
 
-    p_vout->p_sys->b_focus = 0;
     p_vout->p_sys->b_parent_focus = 0;
-
 #else
     p_vout->pf_display = FirstDisplayGDI;
 #endif
 
-    p_vout->p_sys->hwnd = p_vout->p_sys->hvideownd = NULL;
-    p_vout->p_sys->hparent = p_vout->p_sys->hfswnd = NULL;
-    p_vout->p_sys->i_changes = 0;
-    vlc_mutex_init( p_vout, &p_vout->p_sys->lock );
-    SetRectEmpty( &p_vout->p_sys->rect_display );
-    SetRectEmpty( &p_vout->p_sys->rect_parent );
-
-    var_Create( p_vout, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
-    var_Create( p_vout, "disable-screensaver", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-
-    p_vout->p_sys->b_cursor_hidden = 0;
-    p_vout->p_sys->i_lastmoved = mdate();
-
-    /* Set main window's size */
-    p_vout->p_sys->i_window_width = p_vout->i_window_width;
-    p_vout->p_sys->i_window_height = p_vout->i_window_height;
-
-    /* Create the EventThread, this thread is created by us to isolate
-     * the Win32 PeekMessage function calls. We want to do this because
-     * Windows can stay blocked inside this call for a long time, and when
-     * this happens it thus blocks vlc's video_output thread.
-     * Vout EventThread will take care of the creation of the video
-     * window (because PeekMessage has to be called from the same thread which
-     * created the window). */
-    msg_Dbg( p_vout, "creating Vout EventThread" );
-    p_vout->p_sys->p_event =
-        vlc_object_create( p_vout, sizeof(event_thread_t) );
-    p_vout->p_sys->p_event->p_vout = p_vout;
-    if( vlc_thread_create( p_vout->p_sys->p_event, "VLC Vout Events Thread",
-                           E_(EventThread), 0, 1 ) )
-    {
-        msg_Err( p_vout, "cannot create Vout EventThread" );
-        vlc_object_release( p_vout->p_sys->p_event );
-        p_vout->p_sys->p_event = NULL;
+    if( CommonInit( p_vout ) )
         goto error;
-    }
 
-    if( p_vout->p_sys->p_event->b_error )
-    {
-        msg_Err( p_vout, "Vout EventThread failed" );
-        goto error;
-    }
-
-    vlc_object_attach( p_vout->p_sys->p_event, p_vout );
-
-    msg_Dbg( p_vout, "Vout EventThread running" );
-
-#ifndef UNDER_CE
-    /* Variable to indicate if the window should be on top of others */
-    /* Trigger a callback right now */
-    var_Get( p_vout, "video-on-top", &val );
-    var_Set( p_vout, "video-on-top", val );
-
-    /* disable screensaver by temporarily changing system settings */
-    p_vout->p_sys->i_spi_lowpowertimeout = 0;
-    p_vout->p_sys->i_spi_powerofftimeout = 0;
-    p_vout->p_sys->i_spi_screensavetimeout = 0;
-    var_Get( p_vout, "disable-screensaver", &val);
-    if( val.b_bool ) {
-        msg_Dbg(p_vout, "disabling screen saver");
-        SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT,
-            0, &(p_vout->p_sys->i_spi_lowpowertimeout), 0);
-        if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) {
-            SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0);
-        }
-        SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0,
-            &(p_vout->p_sys->i_spi_powerofftimeout), 0);
-        if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) {
-            SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 0, NULL, 0);
-        }
-        SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0,
-            &(p_vout->p_sys->i_spi_screensavetimeout), 0);
-        if( 0 != p_vout->p_sys->i_spi_screensavetimeout ) {
-            SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0);
-        }
-    }
-#endif
     return VLC_SUCCESS;
 
 error:
@@ -310,50 +171,13 @@ static void CloseVideo ( vlc_object_t *p_this )
 {
     vout_thread_t * p_vout = (vout_thread_t *)p_this;
 
-    if( p_vout->p_sys->p_event )
-    {
-        vlc_object_detach( p_vout->p_sys->p_event );
-
-        /* Kill Vout EventThread */
-        vlc_object_kill( p_vout->p_sys->p_event );
-
-        /* we need to be sure Vout EventThread won't stay stuck in
-         * GetMessage, so we send a fake message */
-        if( p_vout->p_sys->hwnd )
-        {
-            PostMessage( p_vout->p_sys->hwnd, WM_NULL, 0, 0);
-        }
-
-        vlc_thread_join( p_vout->p_sys->p_event );
-        vlc_object_release( p_vout->p_sys->p_event );
-    }
-    vlc_mutex_destroy( &p_vout->p_sys->lock );
-
-#ifndef UNDER_CE
-    /* restore screensaver system settings */
-    if( 0 != p_vout->p_sys->i_spi_lowpowertimeout ) {
-        SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT,
-            p_vout->p_sys->i_spi_lowpowertimeout, NULL, 0);
-    }
-    if( 0 != p_vout->p_sys->i_spi_powerofftimeout ) {
-        SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT,
-            p_vout->p_sys->i_spi_powerofftimeout, NULL, 0);
-    }
-    if( 0 != p_vout->p_sys->i_spi_screensavetimeout ) {
-        SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,
-            p_vout->p_sys->i_spi_screensavetimeout, NULL, 0);
-    }
-#endif
+    CommonClean( p_vout );
 
 #ifdef MODULE_NAME_IS_wingapi
     FreeLibrary( p_vout->p_sys->gapi_dll );
 #endif
 
-    if( p_vout->p_sys )
-    {
-        free( p_vout->p_sys );
-        p_vout->p_sys = NULL;
-    }
+    free( p_vout->p_sys );
 }
 
 /*****************************************************************************
@@ -377,29 +201,29 @@ static int Init( vout_thread_t *p_vout )
     switch( p_vout->p_sys->i_depth )
     {
     case 8:
-        p_vout->output.i_chroma = VLC_FOURCC('R','G','B','2');
+        p_vout->output.i_chroma = VLC_CODEC_RGB8;
         p_vout->output.pf_setpalette = SetPalette;
         break;
     case 15:
-        p_vout->output.i_chroma = VLC_FOURCC('R','V','1','5');
+        p_vout->output.i_chroma = VLC_CODEC_RGB15;
         p_vout->output.i_rmask  = 0x7c00;
         p_vout->output.i_gmask  = 0x03e0;
         p_vout->output.i_bmask  = 0x001f;
         break;
     case 16:
-        p_vout->output.i_chroma = VLC_FOURCC('R','V','1','6');
+        p_vout->output.i_chroma = VLC_CODEC_RGB16;
         p_vout->output.i_rmask  = 0xf800;
         p_vout->output.i_gmask  = 0x07e0;
         p_vout->output.i_bmask  = 0x001f;
         break;
     case 24:
-        p_vout->output.i_chroma = VLC_FOURCC('R','V','2','4');
+        p_vout->output.i_chroma = VLC_CODEC_RGB24;
         p_vout->output.i_rmask  = 0x00ff0000;
         p_vout->output.i_gmask  = 0x0000ff00;
         p_vout->output.i_bmask  = 0x000000ff;
         break;
     case 32:
-        p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');
+        p_vout->output.i_chroma = VLC_CODEC_RGB32;
         p_vout->output.i_rmask  = 0x00ff0000;
         p_vout->output.i_gmask  = 0x0000ff00;
         p_vout->output.i_bmask  = 0x000000ff;
@@ -449,7 +273,7 @@ static int Init( vout_thread_t *p_vout )
 
     /* Change the window title bar text */
     PostMessage( p_vout->p_sys->hwnd, WM_VLC_CHANGE_TEXT, 0, 0 );
-    E_(UpdateRects)( p_vout, VLC_TRUE );
+    UpdateRects( p_vout, true );
 
     return VLC_SUCCESS;
 }
@@ -475,67 +299,6 @@ static void End( vout_thread_t *p_vout )
  *****************************************************************************/
 static int Manage( vout_thread_t *p_vout )
 {
-    /* If we do not control our window, we check for geometry changes
-     * ourselves because the parent might not send us its events. */
-    vlc_mutex_lock( &p_vout->p_sys->lock );
-    if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
-    {
-        RECT rect_parent;
-        POINT point;
-
-        vlc_mutex_unlock( &p_vout->p_sys->lock );
-
-        GetClientRect( p_vout->p_sys->hparent, &rect_parent );
-        point.x = point.y = 0;
-        ClientToScreen( p_vout->p_sys->hparent, &point );
-        OffsetRect( &rect_parent, point.x, point.y );
-
-        if( !EqualRect( &rect_parent, &p_vout->p_sys->rect_parent ) )
-        {
-            int i_x, i_y, i_width, i_height;
-            p_vout->p_sys->rect_parent = rect_parent;
-
-            /* This one is to force the update even if only
-             * the position has changed */
-            SetWindowPos( p_vout->p_sys->hwnd, 0, 1, 1,
-                          rect_parent.right - rect_parent.left,
-                          rect_parent.bottom - rect_parent.top, 0 );
-
-            SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
-                          rect_parent.right - rect_parent.left,
-                          rect_parent.bottom - rect_parent.top, 0 );
-
-            vout_PlacePicture( p_vout, rect_parent.right - rect_parent.left,
-                               rect_parent.bottom - rect_parent.top,
-                               &i_x, &i_y, &i_width, &i_height );
-
-            SetWindowPos( p_vout->p_sys->hvideownd, HWND_TOP,
-                          i_x, i_y, i_width, i_height, 0 );
-        }
-    }
-    else
-    {
-        vlc_mutex_unlock( &p_vout->p_sys->lock );
-    }
-
-    /* Check for cropping / aspect changes */
-    if( p_vout->i_changes & VOUT_CROP_CHANGE ||
-        p_vout->i_changes & VOUT_ASPECT_CHANGE )
-    {
-        p_vout->i_changes &= ~VOUT_CROP_CHANGE;
-        p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
-
-        p_vout->fmt_out.i_x_offset = p_vout->fmt_in.i_x_offset;
-        p_vout->fmt_out.i_y_offset = p_vout->fmt_in.i_y_offset;
-        p_vout->fmt_out.i_visible_width = p_vout->fmt_in.i_visible_width;
-        p_vout->fmt_out.i_visible_height = p_vout->fmt_in.i_visible_height;
-        p_vout->fmt_out.i_aspect = p_vout->fmt_in.i_aspect;
-        p_vout->fmt_out.i_sar_num = p_vout->fmt_in.i_sar_num;
-        p_vout->fmt_out.i_sar_den = p_vout->fmt_in.i_sar_den;
-        p_vout->output.i_aspect = p_vout->fmt_in.i_aspect;
-        E_(UpdateRects)( p_vout, VLC_TRUE );
-    }
-
     /*
      * Position Change
      */
@@ -544,83 +307,7 @@ static int Manage( vout_thread_t *p_vout )
         p_vout->p_sys->i_changes &= ~DX_POSITION_CHANGE;
     }
 
-    /* We used to call the Win32 PeekMessage function here to read the window
-     * messages. But since window can stay blocked into this function for a
-     * long time (for example when you move your window on the screen), I
-     * decided to isolate PeekMessage in another thread. */
-
-    /*
-     * Fullscreen change
-     */
-    if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE
-        || p_vout->p_sys->i_changes & VOUT_FULLSCREEN_CHANGE )
-    {
-        Win32ToggleFullscreen( p_vout );
-
-        p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
-        p_vout->p_sys->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
-    }
-
-    /*
-     * Pointer change
-     */
-    if( p_vout->b_fullscreen && !p_vout->p_sys->b_cursor_hidden &&
-        (mdate() - p_vout->p_sys->i_lastmoved) > 5000000 )
-    {
-        POINT point;
-        HWND hwnd;
-
-        /* Hide the cursor only if it is inside our window */
-        GetCursorPos( &point );
-        hwnd = WindowFromPoint(point);
-        if( hwnd == p_vout->p_sys->hwnd || hwnd == p_vout->p_sys->hvideownd )
-        {
-            PostMessage( p_vout->p_sys->hwnd, WM_VLC_HIDE_MOUSE, 0, 0 );
-        }
-        else
-        {
-            p_vout->p_sys->i_lastmoved = mdate();
-        }
-    }
-
-    /*
-     * "Always on top" status change
-     */
-    if( p_vout->p_sys->b_on_top_change )
-    {
-        vlc_value_t val;
-        HMENU hMenu = GetSystemMenu( p_vout->p_sys->hwnd, FALSE );
-
-        var_Get( p_vout, "video-on-top", &val );
-
-        /* Set the window on top if necessary */
-        if( val.b_bool && !( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
-                           & WS_EX_TOPMOST ) )
-        {
-            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
-                           MF_BYCOMMAND | MFS_CHECKED );
-            SetWindowPos( p_vout->p_sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0,
-                          SWP_NOSIZE | SWP_NOMOVE );
-        }
-        else
-        /* The window shouldn't be on top */
-        if( !val.b_bool && ( GetWindowLong( p_vout->p_sys->hwnd, GWL_EXSTYLE )
-                           & WS_EX_TOPMOST ) )
-        {
-            CheckMenuItem( hMenu, IDM_TOGGLE_ON_TOP,
-                           MF_BYCOMMAND | MFS_UNCHECKED );
-            SetWindowPos( p_vout->p_sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
-                          SWP_NOSIZE | SWP_NOMOVE );
-        }
-
-        p_vout->p_sys->b_on_top_change = VLC_FALSE;
-    }
-
-    /* Check if the event thread is still running */
-    if( p_vout->p_sys->p_event->b_die )
-    {
-        return VLC_EGENERIC; /* exit */
-    }
+    CommonManage( p_vout );
 
     return VLC_SUCCESS;
 }
@@ -631,6 +318,8 @@ static int Manage( vout_thread_t *p_vout )
 static void Render( vout_thread_t *p_vout, picture_t *p_pic )
 {
     /* No need to do anything, the fake direct buffers stay as they are */
+    (void)p_vout;
+    (void)p_pic;
 }
 
 /*****************************************************************************
@@ -644,6 +333,8 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
 #ifndef MODULE_NAME_IS_wingapi
 static void DisplayGDI( vout_thread_t *p_vout, picture_t *p_pic )
 {
+    VLC_UNUSED( p_pic );
+
     vout_sys_t *p_sys = p_vout->p_sys;
     RECT rect_dst = rect_dest_clipped;
     HDC hdc = GetDC( p_sys->hvideownd );
@@ -748,8 +439,8 @@ static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic )
             return VLC_EGENERIC;
         }
 
-#if 0
-        msg_Err( p_vout, "video (%d,%d,%d,%d) display (%d,%d,%d,%d) "
+#ifndef NDEBUG
+        msg_Dbg( p_vout, "video (%d,%d,%d,%d) display (%d,%d,%d,%d) "
                  "dest (%d,%d,%d,%d)",
                  video_rect.left, video_rect.right,
                  video_rect.top, video_rect.bottom,
@@ -761,7 +452,7 @@ static int GAPILockSurface( vout_thread_t *p_vout, picture_t *p_pic )
 
         if( !(p_dest = GXBeginDraw()) )
         {
-#if 0
+#ifndef NDEBUG
             msg_Err( p_vout, "GXBeginDraw error %d ", GetLastError() );
 #endif
             return VLC_EGENERIC;
@@ -823,6 +514,7 @@ static void FirstDisplayGAPI( vout_thread_t *p_vout, picture_t *p_pic )
 static void SetPalette( vout_thread_t *p_vout,
                         uint16_t *red, uint16_t *green, uint16_t *blue )
 {
+    VLC_UNUSED( red ); VLC_UNUSED( green );VLC_UNUSED( blue );
     msg_Err( p_vout, "FIXME: SetPalette unimplemented" );
 }
 
@@ -833,7 +525,6 @@ static void InitBuffers( vout_thread_t *p_vout )
 {
     BITMAPINFOHEADER *p_header = &p_vout->p_sys->bitmapinfo.bmiHeader;
     BITMAPINFO *p_info = &p_vout->p_sys->bitmapinfo;
-    int i_pixels = p_vout->render.i_height * p_vout->render.i_width;
     HDC window_dc = GetDC( p_vout->p_sys->hvideownd );
 
     /* Get screen properties */
@@ -910,7 +601,7 @@ static void InitBuffers( vout_thread_t *p_vout )
 
     p_vout->p_sys->off_bitmap =
         CreateDIBSection( window_dc, (BITMAPINFO *)p_header, DIB_RGB_COLORS,
-                          (void**)&p_vout->p_sys->p_pic_buffer, NULL, 0 );
+                          &p_vout->p_sys->p_pic_buffer, NULL, 0 );
 
     p_vout->p_sys->off_dc = CreateCompatibleDC( window_dc );