+ if( IDirectDrawSurface2_Unlock( p_pic->p_sys->p_surface, NULL ) == DD_OK )
+ return VLC_SUCCESS;
+ else
+ return VLC_EGENERIC;
+}
+
+/*****************************************************************************
+ * DirectXFindColorkey: Finds out the 32bits RGB pixel value of the colorkey
+ *****************************************************************************/
+static DWORD DirectXFindColorkey( vout_thread_t *p_vout, uint32_t i_color )
+{
+ DDSURFACEDESC ddsd;
+ HRESULT dxresult;
+ COLORREF i_rgb = 0;
+ uint32_t i_pixel_backup;
+ HDC hdc;
+
+ ddsd.dwSize = sizeof(ddsd);
+ dxresult = IDirectDrawSurface2_Lock( p_vout->p_sys->p_display, NULL,
+ &ddsd, DDLOCK_WAIT, NULL );
+ if( dxresult != DD_OK ) return 0;
+
+ i_pixel_backup = *(uint32_t *)ddsd.lpSurface;
+
+ switch( ddsd.ddpfPixelFormat.dwRGBBitCount )
+ {
+ case 4:
+ *(uint8_t *)ddsd.lpSurface = 0x11;
+ break;
+ case 8:
+ *(uint8_t *)ddsd.lpSurface = 0x01;
+ break;
+ case 16:
+ *(uint16_t *)ddsd.lpSurface = 0x01;
+ break;
+ default:
+ *(uint32_t *)ddsd.lpSurface = 0x01;
+ break;
+ }
+
+ IDirectDrawSurface2_Unlock( p_vout->p_sys->p_display, NULL );
+
+ if( IDirectDrawSurface2_GetDC( p_vout->p_sys->p_display, &hdc ) == DD_OK )
+ {
+ i_rgb = GetPixel( hdc, 0, 0 );
+ IDirectDrawSurface2_ReleaseDC( p_vout->p_sys->p_display, hdc );
+ }
+
+ ddsd.dwSize = sizeof(ddsd);
+ dxresult = IDirectDrawSurface2_Lock( p_vout->p_sys->p_display, NULL,
+ &ddsd, DDLOCK_WAIT, NULL );
+ if( dxresult != DD_OK ) return i_rgb;
+
+ *(uint32_t *)ddsd.lpSurface = i_pixel_backup;
+
+ IDirectDrawSurface2_Unlock( p_vout->p_sys->p_display, NULL );
+
+ return i_rgb;
+}
+
+/*****************************************************************************
+ * A few toolbox functions
+ *****************************************************************************/
+void SwitchWallpaperMode( vout_thread_t *p_vout, vlc_bool_t b_on )
+{
+ HWND hwnd;
+
+ if( p_vout->p_sys->b_wallpaper == b_on ) return; /* Nothing to do */
+
+ hwnd = FindWindow( "Progman", NULL );
+ if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, "SHELLDLL_DefView", NULL );
+ if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, "SysListView32", NULL );
+ if( !hwnd )
+ {
+ msg_Warn( p_vout, "couldn't find \"SysListView32\" window, "
+ "wallpaper mode not supported" );
+ return;
+ }
+
+ p_vout->p_sys->b_wallpaper = b_on;
+
+ msg_Dbg( p_vout, "wallpaper mode %s", b_on ? "enabled" : "disabled" );
+
+ if( p_vout->p_sys->b_wallpaper )
+ {
+ p_vout->p_sys->color_bkg = ListView_GetBkColor( hwnd );
+ p_vout->p_sys->color_bkgtxt = ListView_GetTextBkColor( hwnd );
+
+ ListView_SetBkColor( hwnd, p_vout->p_sys->i_rgb_colorkey );
+ ListView_SetTextBkColor( hwnd, p_vout->p_sys->i_rgb_colorkey );
+ }
+ else if( hwnd )
+ {
+ ListView_SetBkColor( hwnd, p_vout->p_sys->color_bkg );
+ ListView_SetTextBkColor( hwnd, p_vout->p_sys->color_bkgtxt );
+ }
+
+ /* Update desktop */
+ InvalidateRect( hwnd, NULL, TRUE );
+ UpdateWindow( hwnd );
+}
+
+/*****************************************************************************
+ * config variable callback
+ *****************************************************************************/
+BOOL WINAPI DirectXEnumCallback2( GUID* p_guid, LPTSTR psz_desc,
+ LPTSTR psz_drivername, VOID* p_context,
+ HMONITOR hmon )
+{
+ module_config_t *p_item = (module_config_t *)p_context;
+
+ p_item->ppsz_list =
+ (char **)realloc( p_item->ppsz_list,
+ (p_item->i_list+2) * sizeof(char *) );
+ p_item->ppsz_list_text =
+ (char **)realloc( p_item->ppsz_list_text,
+ (p_item->i_list+2) * sizeof(char *) );
+
+ p_item->ppsz_list[p_item->i_list] = strdup( psz_drivername );
+ p_item->ppsz_list_text[p_item->i_list] = NULL;
+ p_item->i_list++;
+ p_item->ppsz_list[p_item->i_list] = NULL;
+ p_item->ppsz_list_text[p_item->i_list] = NULL;
+
+ return TRUE; /* Keep enumerating */
+}
+
+static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
+ vlc_value_t newval, vlc_value_t oldval, void *d)
+{
+ HRESULT (WINAPI *OurDirectDrawEnumerateEx)( LPDDENUMCALLBACKEXA, LPVOID,
+ DWORD );
+ HINSTANCE hddraw_dll;
+
+ module_config_t *p_item;
+ int i;
+
+ p_item = config_FindConfig( p_this, psz_name );
+ if( !p_item ) return VLC_SUCCESS;
+
+ /* Clear-up the current list */
+ if( p_item->i_list )
+ {
+ /* Keep the first entry */
+ for( i = 1; i < p_item->i_list; i++ )
+ {
+ free( p_item->ppsz_list[i] );
+ free( p_item->ppsz_list_text[i] );
+ }
+ /* TODO: Remove when no more needed */
+ p_item->ppsz_list[i] = NULL;
+ p_item->ppsz_list_text[i] = NULL;
+ }
+ p_item->i_list = 1;
+
+ /* Load direct draw DLL */
+ hddraw_dll = LoadLibrary("DDRAW.DLL");
+ if( hddraw_dll == NULL ) return VLC_SUCCESS;
+
+ OurDirectDrawEnumerateEx =
+ (void *)GetProcAddress( hddraw_dll, "DirectDrawEnumerateExA" );
+
+ if( OurDirectDrawEnumerateEx )
+ {
+ /* Enumerate displays */
+ OurDirectDrawEnumerateEx( DirectXEnumCallback2, p_item,
+ DDENUM_ATTACHEDSECONDARYDEVICES );
+ }
+
+ FreeLibrary( hddraw_dll );
+
+ /* Signal change to the interface */
+ p_item->b_dirty = VLC_TRUE;
+
+ return VLC_SUCCESS;
+}
+
+static int WallpaperCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval,
+ void *p_data )
+{
+ vout_thread_t *p_vout = (vout_thread_t *)p_this;
+
+ if( (newval.b_bool && !p_vout->p_sys->b_wallpaper) ||
+ (!newval.b_bool && p_vout->p_sys->b_wallpaper) )
+ {
+ playlist_t *p_playlist;
+
+ p_playlist =
+ (playlist_t *)vlc_object_find( p_this, VLC_OBJECT_PLAYLIST,
+ FIND_PARENT );
+ if( p_playlist )
+ {
+ /* Modify playlist as well because the vout might have to be
+ * restarted */
+ var_Create( p_playlist, "directx-wallpaper", VLC_VAR_BOOL );
+ var_Set( p_playlist, "directx-wallpaper", newval );
+
+ vlc_object_release( p_playlist );
+ }
+
+ p_vout->p_sys->i_changes |= DX_WALLPAPER_CHANGE;
+ }