]> git.sesse.net Git - vlc/blob - modules/gui/skins2/win32/win32_window.cpp
skins2: drap&drop enhancement
[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 "../src/vout_manager.hpp"
30 #include "win32_window.hpp"
31 #include "win32_dragdrop.hpp"
32 #include "win32_factory.hpp"
33
34
35 /// Fading API
36 #ifndef LWA_COLORKEY
37 #   define LWA_COLORKEY  0x00000001
38 #   define LWA_ALPHA     0x00000002
39 #endif
40
41
42 // XXX layered windows are supposed to work only with at least win2k
43 #ifndef WS_EX_LAYERED
44 #   define WS_EX_LAYERED 0x00080000
45 #endif
46
47 Win32Window::Win32Window( intf_thread_t *pIntf, GenericWindow &rWindow,
48                           HINSTANCE hInst, HWND hParentWindow,
49                           bool dragDrop, bool playOnDrop,
50                           Win32Window *pParentWindow,
51                           GenericWindow::WindowType_t type ):
52     OSWindow( pIntf ), m_dragDrop( dragDrop ), m_isLayered( false ),
53     m_pParent( pParentWindow ), m_type ( type )
54 {
55     (void)hParentWindow;
56     Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
57
58     const char* vlc_name =  "VlC Media Player";
59     const char* vlc_class =  "SkinWindowClass";
60
61     // Create the window
62     if( type == GenericWindow::VoutWindow )
63     {
64         // Child window (for vout)
65         m_hWnd_parent = pParentWindow->getHandle();
66         m_hWnd = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_NOPARENTNOTIFY,
67                      vlc_class, vlc_name,
68                      WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
69                      0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL );
70     }
71     else if( type == GenericWindow::FullscreenWindow )
72     {
73         // top-level window
74         m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, vlc_class,
75                                  vlc_name, WS_POPUP | WS_CLIPCHILDREN,
76                                  0, 0, 0, 0, NULL, 0, hInst, NULL );
77
78         // Store with it a pointer to the interface thread
79         SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
80     }
81     else if( type == GenericWindow::FscWindow )
82     {
83         VoutManager* pVoutManager = VoutManager::instance( getIntf() );
84         GenericWindow* pParent =
85            (GenericWindow*)pVoutManager->getVoutMainWindow();
86
87         m_hWnd_parent = (HWND)pParent->getOSHandle();
88
89         // top-level window
90         m_hWnd = CreateWindowEx( WS_EX_APPWINDOW, vlc_class, vlc_name,
91                                  WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
92                                  0, 0, 0, 0, m_hWnd_parent, 0, hInst, NULL );
93
94         // Store with it a pointer to the interface thread
95         SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
96     }
97     else
98     {
99         // top-level window (owned by the root window)
100         HWND hWnd_owner = pFactory->getParentWindow();
101         m_hWnd = CreateWindowEx( 0, vlc_class, vlc_name,
102                                  WS_POPUP | WS_CLIPCHILDREN,
103                                  0, 0, 0, 0, hWnd_owner, 0, hInst, NULL );
104
105         // Store with it a pointer to the interface thread
106         SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)getIntf() );
107     }
108
109     if( !m_hWnd )
110     {
111         msg_Err( getIntf(), "CreateWindow failed" );
112         return;
113     }
114
115     // Store a pointer to the GenericWindow in a map
116     pFactory->m_windowMap[m_hWnd] = &rWindow;
117
118     // Drag & drop
119     if( m_dragDrop )
120     {
121         m_pDropTarget = (LPDROPTARGET)
122             new Win32DragDrop( getIntf(), playOnDrop, &rWindow );
123         // Register the window as a drop target
124         RegisterDragDrop( m_hWnd, m_pDropTarget );
125     }
126 }
127
128
129 Win32Window::~Win32Window()
130 {
131     Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( getIntf() );
132     pFactory->m_windowMap[m_hWnd] = NULL;
133
134     if( m_hWnd )
135     {
136         if( m_dragDrop )
137         {
138             // Remove the window from the list of drop targets
139             RevokeDragDrop( m_hWnd );
140             m_pDropTarget->Release();
141         }
142
143         DestroyWindow( m_hWnd );
144     }
145 }
146
147
148 void Win32Window::reparent( void* OSHandle, int x, int y, int w, int h )
149 {
150     // Reparent the window
151     if( !SetParent( m_hWnd, (HWND)OSHandle ) )
152         msg_Err( getIntf(), "SetParent failed (%lu)", GetLastError() );
153     MoveWindow( m_hWnd, x, y, w, h, TRUE );
154 }
155
156
157 bool Win32Window::invalidateRect( int x, int y, int w, int h) const
158 {
159     RECT rect = { x, y, x + w , y + h };
160     InvalidateRect( m_hWnd, &rect, FALSE );
161     UpdateWindow( m_hWnd );
162
163     return true;
164 }
165
166
167 void Win32Window::show() const
168 {
169
170     if( m_type == GenericWindow::VoutWindow )
171     {
172         SetWindowPos( m_hWnd, HWND_BOTTOM, 0, 0, 0, 0,
173                               SWP_NOMOVE | SWP_NOSIZE );
174     }
175     else if( m_type == GenericWindow::FullscreenWindow )
176     {
177         SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0,
178                               SWP_NOMOVE | SWP_NOSIZE );
179     }
180
181     ShowWindow( m_hWnd, SW_SHOW );
182 }
183
184
185 void Win32Window::hide() const
186 {
187     ShowWindow( m_hWnd, SW_HIDE );
188 }
189
190
191 void Win32Window::moveResize( int left, int top, int width, int height ) const
192 {
193     MoveWindow( m_hWnd, left, top, width, height, TRUE );
194 }
195
196
197 void Win32Window::raise() const
198 {
199 //     SetWindowPos( m_hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
200     SetForegroundWindow( m_hWnd );
201 }
202
203
204 void Win32Window::setOpacity( uint8_t value ) const
205 {
206     if( !m_isLayered )
207     {
208         // add the WS_EX_LAYERED attribute.
209         SetWindowLongPtr( m_hWnd, GWL_EXSTYLE,
210             GetWindowLongPtr( m_hWnd, GWL_EXSTYLE ) | WS_EX_LAYERED );
211
212         m_isLayered = true;
213     }
214
215     // Change the opacity
216     SetLayeredWindowAttributes( m_hWnd, 0, value, LWA_ALPHA );
217 }
218
219
220 void Win32Window::toggleOnTop( bool onTop ) const
221 {
222     SetWindowPos( m_hWnd, onTop ? HWND_TOPMOST : HWND_NOTOPMOST,
223                   0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE );
224 }
225
226
227 #endif