1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2009 the VideoLAN team
7 * Authors: Erwan Tulou <brezhoneg1 at yahoo.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
29 #include <vlc_window.h>
31 #include "vout_manager.hpp"
32 #include "window_manager.hpp"
33 #include "vlcproc.hpp"
34 #include "../commands/async_queue.hpp"
35 #include "../commands/cmd_show_window.hpp"
36 #include "../commands/cmd_resize.hpp"
40 VoutManager *VoutManager::instance( intf_thread_t *pIntf )
42 if( pIntf->p_sys->p_voutManager == NULL )
44 pIntf->p_sys->p_voutManager = new VoutManager( pIntf );
47 return pIntf->p_sys->p_voutManager;
51 void VoutManager::destroy( intf_thread_t *pIntf )
53 if( pIntf->p_sys->p_voutManager )
55 delete pIntf->p_sys->p_voutManager;
56 pIntf->p_sys->p_voutManager = NULL;
61 VoutManager::VoutManager( intf_thread_t *pIntf ): SkinObject( pIntf ),
62 m_pVoutMainWindow( NULL ), m_pCtrlVideoVec(),
63 m_pCtrlVideoVecBackup(), m_SavedVoutVec()
65 vlc_mutex_init( &vout_lock );
67 m_pVoutMainWindow = new VoutMainWindow( getIntf() );
71 VoutManager::~VoutManager( )
73 vlc_mutex_destroy( &vout_lock );
75 delete m_pVoutMainWindow;
79 void VoutManager::registerCtrlVideo( CtrlVideo* p_CtrlVideo )
81 m_pCtrlVideoVec.push_back( p_CtrlVideo );
85 void VoutManager::saveVoutConfig( )
87 // Save width/height to be consistent across themes
88 // and detach Video Controls
89 vector<SavedVout>::iterator it;
90 for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
92 if( (*it).pCtrlVideo )
94 // detach vout thread from VideoControl
95 (*it).pCtrlVideo->detachVoutWindow( );
97 // memorize width/height before VideoControl is destroyed
98 (*it).width = (*it).pCtrlVideo->getPosition()->getWidth();
99 (*it).height = (*it).pCtrlVideo->getPosition()->getHeight();
100 (*it).pCtrlVideo = NULL;
104 // Create a backup copy and reset original for new theme
105 m_pCtrlVideoVecBackup = m_pCtrlVideoVec;
106 m_pCtrlVideoVec.clear();
110 void VoutManager::restoreVoutConfig( bool b_success )
114 // loading new theme failed, restoring previous theme
115 m_pCtrlVideoVec = m_pCtrlVideoVecBackup;
118 // reattach vout(s) to Video Controls
119 vector<SavedVout>::iterator it;
120 for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
122 CtrlVideo* pCtrlVideo = getBestCtrlVideo();
125 pCtrlVideo->attachVoutWindow( (*it).pVoutWindow );
126 (*it).pCtrlVideo = pCtrlVideo;
132 void VoutManager::discardVout( CtrlVideo* pCtrlVideo )
134 vector<SavedVout>::iterator it;
135 for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
137 if( (*it).pCtrlVideo == pCtrlVideo )
139 // detach vout thread from VideoControl
140 (*it).pCtrlVideo->detachVoutWindow( );
141 (*it).width = (*it).pCtrlVideo->getPosition()->getWidth();
142 (*it).height = (*it).pCtrlVideo->getPosition()->getHeight();
143 (*it).pCtrlVideo = NULL;
150 void VoutManager::requestVout( CtrlVideo* pCtrlVideo )
152 vector<SavedVout>::iterator it;
153 for( it = m_SavedVoutVec.begin(); it != m_SavedVoutVec.end(); it++ )
155 if( (*it).pCtrlVideo == NULL )
157 pCtrlVideo->attachVoutWindow( (*it).pVoutWindow );
158 (*it).pCtrlVideo = pCtrlVideo;
165 CtrlVideo* VoutManager::getBestCtrlVideo( )
167 // try to find an unused useable VideoControl
169 vector<CtrlVideo*>::const_iterator it;
170 for( it = m_pCtrlVideoVec.begin(); it != m_pCtrlVideoVec.end(); it++ )
172 if( (*it)->isUseable() && !(*it)->isUsed() )
182 void* VoutManager::acceptVout( vout_thread_t* pVout, int width, int height )
184 // Creation of a dedicated Window per vout thread
185 VoutWindow* pVoutWindow = new VoutWindow( getIntf(), pVout, width, height,
186 (GenericWindow*) m_pVoutMainWindow );
188 void* handle = pVoutWindow->getOSHandle();
190 // try to find a video Control within the theme
191 CtrlVideo* pCtrlVideo = getBestCtrlVideo();
194 // A Video Control is available
195 // directly attach vout thread to it
196 pCtrlVideo->attachVoutWindow( pVoutWindow );
199 // save vout characteristics
200 m_SavedVoutVec.push_back( SavedVout( pVout, pVoutWindow, pCtrlVideo ) );
202 msg_Dbg( getIntf(), "New incoming vout=0x%x, handle=0x%x, VideoCtrl=0x%x",
203 pVout, handle, pCtrlVideo );
209 // Functions called by window provider
210 // ///////////////////////////////////
212 void *VoutManager::getWindow( intf_thread_t *pIntf, vout_window_t *pWnd )
214 // Theme may have been destroyed
215 if( !pIntf->p_sys->p_theme )
218 VoutManager *pThis = pIntf->p_sys->p_voutManager;
220 vout_thread_t* pVout = pWnd->vout;
221 int width = (int)pWnd->width;
222 int height = (int)pWnd->height;
226 void* handle = pThis->acceptVout( pVout, width, height );
234 void VoutManager::releaseWindow( intf_thread_t *pIntf, vout_window_t *pWnd )
236 VoutManager *pThis = pIntf->p_sys->p_voutManager;
238 // Theme may have been destroyed
239 if( !pIntf->p_sys->p_theme )
242 vout_thread_t* pVout = pWnd->vout;
246 // remove vout thread from savedVec
247 vector<SavedVout>::iterator it;
248 for( it = pThis->m_SavedVoutVec.begin(); it != pThis->m_SavedVoutVec.end(); it++ )
250 if( (*it).pVout == pVout )
252 msg_Dbg( pIntf, "vout released vout=0x%x, VideoCtrl=0x%x",
253 pVout, (*it).pCtrlVideo );
255 // if a video control was being used, detach from it
256 if( (*it).pCtrlVideo )
258 (*it).pCtrlVideo->detachVoutWindow( );
262 delete (*it).pVoutWindow;
263 pThis->m_SavedVoutVec.erase( it );
272 int VoutManager::controlWindow( struct vout_window_t *pWnd,
273 int query, va_list args )
275 intf_thread_t *pIntf = (intf_thread_t *)pWnd->p_private;
276 VoutManager *pThis = pIntf->p_sys->p_voutManager;
282 unsigned int i_width = va_arg( args, unsigned int );
283 unsigned int i_height = va_arg( args, unsigned int );
285 if( i_width && i_height )
287 // Post a resize vout command
288 CmdResizeVout *pCmd =
289 new CmdResizeVout( pThis->getIntf(), pWnd->handle.hwnd,
291 AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
292 pQueue->push( CmdGenericPtr( pCmd ) );
297 msg_Dbg( pWnd, "control query not supported" );