]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/win32/win32_window.cpp
skins2: rework and simplify transparency
[vlc] / modules / gui / skins2 / win32 / win32_window.cpp
index 5a52a577a7e75acf6961ad09ac828e071df7b192..cf771769eedd00cfd0eb2a9fae63157fddcfe6a0 100644 (file)
@@ -1,11 +1,11 @@
 /*****************************************************************************
  * win32_window.cpp
  *****************************************************************************
- * Copyright (C) 2003 VideoLAN
+ * Copyright (C) 2003 the VideoLAN team
  * $Id$
  *
  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
- *          Olivier Teulière <ipkiss@via.ecp.fr>
+ *          Olivier Teulière <ipkiss@via.ecp.fr>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 #ifdef WIN32_SKINS
 
 #include "../src/generic_window.hpp"
+#include "../src/vlcproc.hpp"
 #include "win32_window.hpp"
 #include "win32_dragdrop.hpp"
 #include "win32_factory.hpp"
 
 
 /// Fading API
-#define LWA_COLORKEY  0x00000001
-#define LWA_ALPHA     0x00000002
+#ifndef LWA_COLORKEY
+#   define LWA_COLORKEY  0x00000001
+#   define LWA_ALPHA     0x00000002
+#endif
+
 
+// XXX layered windows are supposed to work only with at least win2k
+#ifndef WS_EX_LAYERED
+#   define WS_EX_LAYERED 0x00080000
+#endif
 
 Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
                           HINSTANCE hInst, HWND hParentWindow,
-                          bool dragDrop, bool playOnDrop ):
-    OSWindow( pIntf ), m_dragDrop( dragDrop ), m_mm( false )
+                          bool dragDrop, bool playOnDrop,
+                          Win32Window *pParentWindow,
+                          GenericWindow::WindowType_t type ):
+    OSWindow( pIntf ), m_dragDrop( dragDrop ), m_isLayered( false ),
+    m_pParent( pParentWindow ), m_type ( type )
 {
+    Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
+
     // Create the window
-    m_hWnd = CreateWindowEx( WS_EX_TOOLWINDOW,
-        "SkinWindowClass", "default name", WS_POPUP, CW_USEDEFAULT,
-        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hParentWindow, 0,
-        hInst, NULL );
+    if( type == GenericWindow::VoutWindow )
+    {
+        // Child window (for vout)
+        m_hWnd_parent = pParentWindow->getHandle();
+        m_hWnd = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_NOPARENTNOTIFY,
+                     "SkinWindowClass", "default name",
+                     WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+                     0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL );
+    }
+    else if( type == GenericWindow::FullscreenWindow )
+    {
+        // top-level window
+        m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, "SkinWindowClass",
+            "default name", WS_POPUP | WS_CLIPCHILDREN,
+            0, 0, 0, 0, NULL, 0, hInst, NULL );
+
+        // Store with it a pointer to the interface thread
+        SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
+    }
+    else
+    {
+        // top-level window (owned by the root window)
+        HWND hWnd_owner = pFactory->getParentWindow();
+        m_hWnd = CreateWindowEx( 0, "SkinWindowClass",
+            "default name", WS_POPUP | WS_CLIPCHILDREN,
+            0, 0, 0, 0, hWnd_owner, 0, hInst, NULL );
+
+        // Store with it a pointer to the interface thread
+        SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
+    }
 
     if( !m_hWnd )
     {
@@ -52,13 +91,7 @@ Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
         return;
     }
 
-    // We do it this way otherwise CreateWindowEx will fail if WS_EX_LAYERED
-    // is not supported
-//    SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
-//                      GetWindowLong( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
-
     // Store a pointer to the GenericWindow in a map
-    Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
     pFactory->m_windowMap[m_hWnd] = &rWindow;
 
     // Drag & drop
@@ -91,8 +124,45 @@ Win32Window::~Win32Window()
 }
 
 
-void Win32Window::show( int left, int top ) const
+void Win32Window::reparent( void* OSHandle, int x, int y, int w, int h )
 {
+    // Reparent the window
+
+    if( m_type == GenericWindow::TopWindow )
+    {
+       // fullscreen controller
+       SetWindowLongPtr( m_hWnd, GWL_STYLE, WS_CHILD );
+    }
+
+    SetParent( m_hWnd, (HWND)OSHandle );
+    MoveWindow( m_hWnd, x, y, w, h, TRUE );
+}
+
+
+bool Win32Window::invalidateRect( int x, int y, int w, int h) const
+{
+    RECT rect = { x, y, x + w , y + h };
+    InvalidateRect( m_hWnd, &rect, FALSE );
+    UpdateWindow( m_hWnd );
+
+    return true;
+}
+
+
+void Win32Window::show() const
+{
+
+    if( m_type == GenericWindow::VoutWindow )
+    {
+        SetWindowPos( m_hWnd, HWND_BOTTOM, 0, 0, 0, 0,
+                              SWP_NOMOVE | SWP_NOSIZE );
+    }
+    else if( m_type == GenericWindow::FullscreenWindow )
+    {
+        SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0,
+                              SWP_NOMOVE | SWP_NOSIZE );
+    }
+
     ShowWindow( m_hWnd, SW_SHOW );
 }
 
@@ -105,79 +175,39 @@ void Win32Window::hide() const
 
 void Win32Window::moveResize( int left, int top, int width, int height ) const
 {
-    MoveWindow( m_hWnd, left, top, width, height, true );
+    MoveWindow( m_hWnd, left, top, width, height, TRUE );
 }
 
 
 void Win32Window::raise() const
 {
-    SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+//     SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
+    SetForegroundWindow( m_hWnd );
 }
 
 
-void Win32Window::setOpacity( uint8_t value )
+void Win32Window::setOpacity( uint8_t value ) const
 {
     Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
-#if 0
-    if( value == 255 )
-    {
-        // If the window is opaque, we remove the WS_EX_LAYERED attribute
-        // which slows resizing for nothing
-        if( m_mm )
-        {
-            SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
-                GetWindowLong( m_hWnd, GWL_EXSTYLE ) & !WS_EX_LAYERED );
-            SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0,
-                SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
-            m_mm = false;
-        }
-//    GenericWindow *pWin = pFactory->m_windowMap[m_hWnd];
-//    pWin->refresh( pWin->getLeft(), pWin->getTop(), pWin->getWidth(), pWin->getHeight() );
 
-    }
-    else
-#endif
+    if( !m_isLayered )
     {
-        if( pFactory->SetLayeredWindowAttributes )
-        {
-#if 0
-            // (Re)Add the WS_EX_LAYERED attribute.
-            // Resizing will be very slow, now :)
-            if( !m_mm )
-            {
-                SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
-                    GetWindowLong( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
-                SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0,
-                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
-                m_mm = true;
-            }
-//    GenericWindow *pWin = pFactory->m_windowMap[m_hWnd];
-//    pWin->refresh( pWin->getLeft(), pWin->getTop(), pWin->getWidth(), pWin->getHeight() );
-#endif
-            // Change the opacity
-            pFactory->SetLayeredWindowAttributes(
-                m_hWnd, 0, value, LWA_ALPHA|LWA_COLORKEY );
-        }
+        // add the WS_EX_LAYERED attribute.
+        SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
+            GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
+
+        m_isLayered = true;
     }
 
-//    UpdateWindow( m_hWnd );
+    // Change the opacity
+    SetLayeredWindowAttributes( m_hWnd, 0, value, LWA_ALPHA );
 }
 
 
 void Win32Window::toggleOnTop( bool onTop ) const
 {
-    if( onTop )
-    {
-        // Set the window on top
-        SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0,
-                      SWP_NOSIZE | SWP_NOMOVE );
-    }
-    else
-    {
-        // Set the window not on top
-        SetWindowPos( m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
-                      SWP_NOSIZE | SWP_NOMOVE );
-    }
+    SetWindowPos( m_hWnd, onTop ? HWND_TOPMOST : HWND_NOTOPMOST,
+                  0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
 }