]> git.sesse.net Git - vlc/blobdiff - modules/video_output/msw/events.c
Win32: add support for Win 7 taskbar thumbnails
[vlc] / modules / video_output / msw / events.c
index db9b27ef106996f509e32b0bf57af0de8f4ac876..365ee1ac614d8ea98eb7c65aeb5ae5a88705e550 100644 (file)
@@ -41,7 +41,7 @@
 #include <vlc_interface.h>
 #include <vlc_playlist.h>
 #include <vlc_vout.h>
-#include <vlc_window.h>
+#include <vlc_vout_window.h>
 
 #include <windows.h>
 #include <tchar.h>
 #include <vlc_keys.h>
 #include "vout.h"
 
+#ifndef UNDER_CE
+#include <vlc_windows_interfaces.h>
+#endif
+
 #ifdef UNDER_CE
 #include <aygshell.h>
     //WINSHELLAPI BOOL WINAPI SHFullScreen(HWND hwndRequester, DWORD dwState);
@@ -343,7 +347,6 @@ void* EventThread( vlc_object_t *p_this )
 #endif
             }
 
-#ifdef UNICODE
             {
                 wchar_t *psz_title = malloc( strlen(val.psz_string) * 2 + 2 );
                 if( psz_title )
@@ -353,7 +356,6 @@ void* EventThread( vlc_object_t *p_this )
                     free( val.psz_string ); val.psz_string = (char *)psz_title;
                 }
             }
-#endif
 
             SetWindowText( p_event->p_vout->p_sys->hwnd,
                            (LPCTSTR)val.psz_string );
@@ -383,11 +385,11 @@ void* EventThread( vlc_object_t *p_this )
 
     msg_Dbg( p_event, "DirectXEventThread terminating" );
 
-    /* clear the changes formerly signaled */
-    p_event->p_vout->p_sys->i_changes = 0;
-
     DirectXCloseWindow( p_event->p_vout );
     vlc_restorecancel (canc);
+
+    /* clear the changes formerly signaled */
+    p_event->p_vout->p_sys->i_changes = EVENT_THREAD_ENDED;
     return NULL;
 }
 
@@ -416,14 +418,35 @@ static int DirectXCreateWindow( vout_thread_t *p_vout )
     /* Get this module's instance */
     hInstance = GetModuleHandle(NULL);
 
-    /* If an external window was specified, we'll draw in it. */
-    p_vout->p_sys->parent_window =
-        vout_RequestHWND( p_vout, &p_vout->p_sys->i_window_x,
-                            &p_vout->p_sys->i_window_y,
-                            &p_vout->p_sys->i_window_width,
-                            &p_vout->p_sys->i_window_height );
-    if( p_vout->p_sys->parent_window )
-        p_vout->p_sys->hparent = p_vout->p_sys->parent_window->handle.hwnd;
+    #ifdef MODULE_NAME_IS_direct3d
+    if( !p_vout->p_sys->b_desktop )
+    {
+    #endif
+        vout_window_cfg_t wnd_cfg;
+        memset( &wnd_cfg, 0, sizeof(wnd_cfg) );
+        wnd_cfg.type   = VOUT_WINDOW_TYPE_HWND;
+        wnd_cfg.x      = p_vout->p_sys->i_window_x;
+        wnd_cfg.y      = p_vout->p_sys->i_window_y;
+        wnd_cfg.width  = p_vout->p_sys->i_window_width;
+        wnd_cfg.height = p_vout->p_sys->i_window_height;
+
+        /* If an external window was specified, we'll draw in it. */
+        p_vout->p_sys->parent_window = vout_window_New( VLC_OBJECT(p_vout), NULL, &wnd_cfg );
+        if( p_vout->p_sys->parent_window )
+            p_vout->p_sys->hparent = p_vout->p_sys->parent_window->handle.hwnd;
+    #ifdef MODULE_NAME_IS_direct3d
+    }
+    else
+    {
+        /* Find Program Manager */
+        HWND hwnd = FindWindow( _T("Progman"), NULL );
+        if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SHELLDLL_DefView"), NULL );
+        if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SysListView32"), NULL );
+        if( !hwnd )
+            msg_Err( p_vout, "Couldn't find desktop icon window. Desktop mode can't be established." );
+        p_vout->p_sys->hparent = hwnd;
+    }
+    #endif
 
     /* We create the window ourself, there is no previous window proc. */
     p_vout->p_sys->pf_wndproc = NULL;
@@ -601,7 +624,10 @@ static void DirectXCloseWindow( vout_thread_t *p_vout )
     DestroyWindow( p_vout->p_sys->hwnd );
     if( p_vout->p_sys->hfswnd ) DestroyWindow( p_vout->p_sys->hfswnd );
 
-    vout_ReleaseWindow( p_vout->p_sys->parent_window );
+    #ifdef MODULE_NAME_IS_direct3d
+    if( !p_vout->p_sys->b_desktop )
+    #endif
+        vout_window_Delete( p_vout->p_sys->parent_window );
     p_vout->p_sys->hwnd = NULL;
 
     /* We don't unregister the Window Class because it could lead to race
@@ -623,7 +649,7 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
 #define rect_dest p_vout->p_sys->rect_dest
 #define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
 
-    int i_width, i_height, i_x, i_y;
+    unsigned int i_width, i_height, i_x, i_y;
 
     RECT  rect;
     POINT point;
@@ -693,7 +719,7 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
 
 #ifndef NDEBUG
     msg_Dbg( p_vout, "DirectXUpdateRects image_dst_clipped coords:"
-                     " %i,%i,%i,%i",
+                     " %li,%li,%li,%li",
                      rect_dest_clipped.left, rect_dest_clipped.top,
                      rect_dest_clipped.right, rect_dest_clipped.bottom );
 #endif
@@ -754,7 +780,7 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
 
 #ifndef NDEBUG
     msg_Dbg( p_vout, "DirectXUpdateRects image_src_clipped"
-                     " coords: %i,%i,%i,%i",
+                     " coords: %li,%li,%li,%li",
                      rect_src_clipped.left, rect_src_clipped.top,
                      rect_src_clipped.right, rect_src_clipped.bottom );
 #endif
@@ -771,6 +797,39 @@ void UpdateRects( vout_thread_t *p_vout, bool b_force )
         DirectDrawUpdateOverlay( p_vout );
 #endif
 
+#ifndef UNDER_CE
+    /* Windows 7 taskbar thumbnail code */
+    LPTASKBARLIST3 p_taskbl;
+    OSVERSIONINFO winVer;
+    winVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    if( GetVersionEx(&winVer) && winVer.dwMajorVersion > 5 && winVer.dwMajorVersion > 0 )
+    {
+        CoInitialize( 0 );
+
+        if( S_OK == CoCreateInstance( &clsid_ITaskbarList,
+                    NULL, CLSCTX_INPROC_SERVER,
+                    &IID_ITaskbarList3,
+                    (void **)&p_taskbl) )
+        {
+            RECT rect_video, rect_parent, rect_relative;
+            HWND hroot = GetAncestor(p_vout->p_sys->hwnd,GA_ROOT);
+
+            p_taskbl->vt->HrInit(p_taskbl);
+            GetWindowRect(p_vout->p_sys->hvideownd, &rect_video);
+            GetWindowRect(hroot, &rect_parent);
+            rect_relative.left = rect_video.left - rect_parent.left - 8;
+            rect_relative.right = rect_video.right - rect_video.left + rect_relative.left;
+            rect_relative.top = rect_video.top - rect_parent.top - 10;
+            rect_relative.bottom = rect_video.bottom - rect_video.top + rect_relative.top - 25;
+
+            if (S_OK != p_taskbl->vt->SetThumbnailClip(p_taskbl, hroot, &rect_relative))
+                msg_Err( p_vout, "SetThumbNailClip failed");
+
+            p_taskbl->vt->Release(p_taskbl);
+        }
+        CoUninitialize();
+    }
+#endif
     /* Signal the change in size/position */
     p_vout->p_sys->i_changes |= DX_POSITION_CHANGE;
 
@@ -805,7 +864,8 @@ static long FAR PASCAL DirectXEventProc( HWND hwnd, UINT message,
     }
     else
     {
-        p_vout = (vout_thread_t *)GetWindowLongPtr( hwnd, GWLP_USERDATA );
+        LONG_PTR p_user_data = GetWindowLongPtr( hwnd, GWLP_USERDATA );
+        p_vout = (vout_thread_t *)p_user_data;
         if( !p_vout )
         {
             /* Hmmm mozilla does manage somehow to save the pointer to our
@@ -1037,10 +1097,7 @@ static int DirectXConvertKey( int i_key )
  *****************************************************************************/
 static int Control( vout_thread_t *p_vout, int i_query, va_list args )
 {
-    unsigned int *pi_width, *pi_height;
-       bool b_bool;
     RECT rect_window;
-    POINT point;
 
     switch( i_query )
     {
@@ -1088,9 +1145,25 @@ static WINDOWPLACEMENT getWindowState(HWND hwnd)
 static int vaControlParentWindow( vout_thread_t *p_vout, int i_query,
                                    va_list args )
 {
-    return vout_ControlWindow( p_vout->p_sys->parent_window, i_query, args );
+    switch( i_query )
+    {
+    case VOUT_SET_SIZE:
+    {
+        const unsigned i_width  = va_arg(args, unsigned);
+        const unsigned i_height = va_arg(args, unsigned);
+        return vout_window_SetSize( p_vout->p_sys->parent_window, i_width, i_height );
+    }
+    case VOUT_SET_STAY_ON_TOP:
+    {
+        const bool is_on_top = va_arg(args, int);
+        return vout_window_SetOnTop( p_vout->p_sys->parent_window, is_on_top );
+    }
+    default:
+        return VLC_EGENERIC;
+    }
 }
 
+#if 0
 static int ControlParentWindow( vout_thread_t *p_vout, int i_query, ... )
 {
     va_list args;
@@ -1101,6 +1174,7 @@ static int ControlParentWindow( vout_thread_t *p_vout, int i_query, ... )
     va_end( args );
     return ret;
 }
+#endif
 
 void Win32ToggleFullscreen( vout_thread_t *p_vout )
 {
@@ -1137,7 +1211,7 @@ void Win32ToggleFullscreen( vout_thread_t *p_vout )
             *on the right screen */
             HMONITOR hmon = MonitorFromWindow(p_vout->p_sys->hparent,
                                             MONITOR_DEFAULTTONEAREST);
-            MONITORINFO mi = {sizeof(mi)};
+            MONITORINFO mi;
             if (GetMonitorInfo(hmon, &mi))
             SetWindowPos( hwnd, 0,
                             mi.rcMonitor.left,
@@ -1212,6 +1286,7 @@ void Win32ToggleFullscreen( vout_thread_t *p_vout )
     var_SetBool( p_vout, "fullscreen", p_vout->b_fullscreen );
 }
 
+#ifndef UNDER_CE
 void DisableScreensaver( vout_thread_t *p_vout )
 {
     /* disable screensaver by temporarily changing system settings */
@@ -1255,6 +1330,7 @@ void RestoreScreensaver( vout_thread_t *p_vout )
             p_vout->p_sys->i_spi_screensavetimeout, NULL, 0);
     }
 }
+#endif
 
 int CreateEventThread( vout_thread_t *p_vout )
 {
@@ -1322,5 +1398,6 @@ void StopEventThread( vout_thread_t *p_vout )
         vlc_object_release( p_vout->p_sys->p_event );
     }
 
-    vlc_mutex_destroy( &p_vout->p_sys->lock );
+    if( !( p_vout->p_sys->i_changes & SWITCHING_MODE_FLAG ) )
+        vlc_mutex_destroy( &p_vout->p_sys->lock );
 }