]> git.sesse.net Git - vlc/blob - modules/gui/skins2/win32/win32_window.cpp
skins2: rework and simplify transparency
[vlc] / modules / gui / skins2 / win32 / win32_window.cpp
1 /*****************************************************************************
2  * win32_window.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef WIN32_SKINS
26
27 #include "../src/generic_window.hpp"
28 #include "../src/vlcproc.hpp"
29 #include "win32_window.hpp"
30 #include "win32_dragdrop.hpp"
31 #include "win32_factory.hpp"
32
33
34 /// Fading API
35 #ifndef LWA_COLORKEY
36 #   define LWA_COLORKEY  0x00000001
37 #   define LWA_ALPHA     0x00000002
38 #endif
39
40
41 // XXX layered windows are supposed to work only with at least win2k
42 #ifndef WS_EX_LAYERED
43 #   define WS_EX_LAYERED 0x00080000
44 #endif
45
46 Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
47                           HINSTANCE hInst, HWND hParentWindow,
48                           bool dragDrop, bool playOnDrop,
49                           Win32Window *pParentWindow,
50                           GenericWindow::WindowType_t type ):
51     OSWindow( pIntf ), m_dragDrop( dragDrop ), m_isLayered( false ),
52     m_pParent( pParentWindow ), m_type ( type )
53 {
54     Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
55
56     // Create the window
57     if( type == GenericWindow::VoutWindow )
58     {
59         // Child window (for vout)
60         m_hWnd_parent = pParentWindow->getHandle();
61         m_hWnd = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_NOPARENTNOTIFY,
62                      "SkinWindowClass", "default name",
63                      WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
64                      0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL );
65     }
66     else if( type == GenericWindow::FullscreenWindow )
67     {
68         // top-level window
69         m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, "SkinWindowClass",
70             "default name", WS_POPUP | WS_CLIPCHILDREN,
71             0, 0, 0, 0, NULL, 0, hInst, NULL );
72
73         // Store with it a pointer to the interface thread
74         SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
75     }
76     else
77     {
78         // top-level window (owned by the root window)
79         HWND hWnd_owner = pFactory->getParentWindow();
80         m_hWnd = CreateWindowEx( 0, "SkinWindowClass",
81             "default name", WS_POPUP | WS_CLIPCHILDREN,
82             0, 0, 0, 0, hWnd_owner, 0, hInst, NULL );
83
84         // Store with it a pointer to the interface thread
85         SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
86     }
87
88     if( !m_hWnd )
89     {
90         msg_Err( getIntf(), "CreateWindow failed" );
91         return;
92     }
93
94     // Store a pointer to the GenericWindow in a map
95     pFactory->m_windowMap[m_hWnd] = &rWindow;
96
97     // Drag & drop
98     if( m_dragDrop )
99     {
100         m_pDropTarget = (LPDROPTARGET) new Win32DragDrop( getIntf(),
101                                                           playOnDrop );
102         // Register the window as a drop target
103         RegisterDragDrop( m_hWnd, m_pDropTarget );
104     }
105 }
106
107
108 Win32Window::~Win32Window()
109 {
110     Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
111     pFactory->m_windowMap[m_hWnd] = NULL;
112
113     if( m_hWnd )
114     {
115         if( m_dragDrop )
116         {
117             // Remove the window from the list of drop targets
118             RevokeDragDrop( m_hWnd );
119             m_pDropTarget->Release();
120         }
121
122         DestroyWindow( m_hWnd );
123     }
124 }
125
126
127 void Win32Window::reparent( void* OSHandle, int x, int y, int w, int h )
128 {
129     // Reparent the window
130
131     if( m_type == GenericWindow::TopWindow )
132     {
133        // fullscreen controller
134        SetWindowLongPtr( m_hWnd, GWL_STYLE, WS_CHILD );
135     }
136
137     SetParent( m_hWnd, (HWND)OSHandle );
138     MoveWindow( m_hWnd, x, y, w, h, TRUE );
139 }
140
141
142 bool Win32Window::invalidateRect( int x, int y, int w, int h) const
143 {
144     RECT rect = { x, y, x + w , y + h };
145     InvalidateRect( m_hWnd, &rect, FALSE );
146     UpdateWindow( m_hWnd );
147
148     return true;
149 }
150
151
152 void Win32Window::show() const
153 {
154
155     if( m_type == GenericWindow::VoutWindow )
156     {
157         SetWindowPos( m_hWnd, HWND_BOTTOM, 0, 0, 0, 0,
158                               SWP_NOMOVE | SWP_NOSIZE );
159     }
160     else if( m_type == GenericWindow::FullscreenWindow )
161     {
162         SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0,
163                               SWP_NOMOVE | SWP_NOSIZE );
164     }
165
166     ShowWindow( m_hWnd, SW_SHOW );
167 }
168
169
170 void Win32Window::hide() const
171 {
172     ShowWindow( m_hWnd, SW_HIDE );
173 }
174
175
176 void Win32Window::moveResize( int left, int top, int width, int height ) const
177 {
178     MoveWindow( m_hWnd, left, top, width, height, TRUE );
179 }
180
181
182 void Win32Window::raise() const
183 {
184 //     SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
185     SetForegroundWindow( m_hWnd );
186 }
187
188
189 void Win32Window::setOpacity( uint8_t value ) const
190 {
191     Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
192
193     if( !m_isLayered )
194     {
195         // add the WS_EX_LAYERED attribute.
196         SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
197             GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
198
199         m_isLayered = true;
200     }
201
202     // Change the opacity
203     SetLayeredWindowAttributes( m_hWnd, 0, value, LWA_ALPHA );
204 }
205
206
207 void Win32Window::toggleOnTop( bool onTop ) const
208 {
209     SetWindowPos( m_hWnd, onTop ? HWND_TOPMOST : HWND_NOTOPMOST,
210                   0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
211 }
212
213
214 #endif