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_vout_display.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"
37 #include "../commands/cmd_voutwindow.hpp"
38 #include "../commands/cmd_on_top.hpp"
42 VoutManager
*VoutManager::instance( intf_thread_t
*pIntf
)
44 if( pIntf
->p_sys
->p_voutManager
== NULL
)
46 pIntf
->p_sys
->p_voutManager
= new VoutManager( pIntf
);
49 return pIntf
->p_sys
->p_voutManager
;
53 void VoutManager::destroy( intf_thread_t
*pIntf
)
55 delete pIntf
->p_sys
->p_voutManager
;
56 pIntf
->p_sys
->p_voutManager
= NULL
;
60 VoutManager::VoutManager( intf_thread_t
*pIntf
): SkinObject( pIntf
),
61 m_pVoutMainWindow( NULL
), m_pFscWindow( NULL
), m_pCtrlVideoVec(),
62 m_pCtrlVideoVecBackup(), m_SavedWndVec()
64 m_pVoutMainWindow
= new VoutMainWindow( getIntf() );
66 OSFactory
*pOsFactory
= OSFactory::instance( getIntf() );
67 int width
= pOsFactory
->getScreenWidth();
68 int height
= pOsFactory
->getScreenHeight();
70 m_pVoutMainWindow
->move( 0, 0 );
71 m_pVoutMainWindow
->resize( width
, height
);
75 VoutManager::~VoutManager( )
77 delete m_pVoutMainWindow
;
81 void VoutManager::registerCtrlVideo( CtrlVideo
* p_CtrlVideo
)
83 m_pCtrlVideoVec
.push_back( p_CtrlVideo
);
87 void VoutManager::registerFSC( TopWindow
* p_Win
)
91 int x
= p_Win
->getLeft();
92 int y
= p_Win
->getTop();
93 p_Win
->setParent( m_pVoutMainWindow
, x
, y
, 0, 0 );
97 void VoutManager::saveVoutConfig( )
99 // Save width/height to be consistent across themes
100 // and detach Video Controls
101 vector
<SavedWnd
>::iterator it
;
102 for( it
= m_SavedWndVec
.begin(); it
!= m_SavedWndVec
.end(); it
++ )
104 if( (*it
).pCtrlVideo
)
106 // detach vout thread from VideoControl
107 (*it
).pCtrlVideo
->detachVoutWindow( );
109 // memorize width/height before VideoControl is destroyed
110 (*it
).width
= (*it
).pCtrlVideo
->getPosition()->getWidth();
111 (*it
).height
= (*it
).pCtrlVideo
->getPosition()->getHeight();
112 (*it
).pCtrlVideo
= NULL
;
116 // Create a backup copy and reset original for new theme
117 m_pCtrlVideoVecBackup
= m_pCtrlVideoVec
;
118 m_pCtrlVideoVec
.clear();
122 void VoutManager::restoreVoutConfig( bool b_success
)
126 // loading new theme failed, restoring previous theme
127 m_pCtrlVideoVec
= m_pCtrlVideoVecBackup
;
130 // reattach vout(s) to Video Controls
131 vector
<SavedWnd
>::iterator it
;
132 for( it
= m_SavedWndVec
.begin(); it
!= m_SavedWndVec
.end(); it
++ )
134 CtrlVideo
* pCtrlVideo
= getBestCtrlVideo();
137 pCtrlVideo
->attachVoutWindow( (*it
).pVoutWindow
);
138 (*it
).pCtrlVideo
= pCtrlVideo
;
144 void VoutManager::discardVout( CtrlVideo
* pCtrlVideo
)
146 vector
<SavedWnd
>::iterator it
;
147 for( it
= m_SavedWndVec
.begin(); it
!= m_SavedWndVec
.end(); it
++ )
149 if( (*it
).pCtrlVideo
== pCtrlVideo
)
151 // detach vout thread from VideoControl
152 (*it
).pCtrlVideo
->detachVoutWindow( );
153 (*it
).width
= (*it
).pCtrlVideo
->getPosition()->getWidth();
154 (*it
).height
= (*it
).pCtrlVideo
->getPosition()->getHeight();
155 (*it
).pCtrlVideo
= NULL
;
162 void VoutManager::requestVout( CtrlVideo
* pCtrlVideo
)
164 vector
<SavedWnd
>::iterator it
;
165 for( it
= m_SavedWndVec
.begin(); it
!= m_SavedWndVec
.end(); it
++ )
167 if( (*it
).pCtrlVideo
== NULL
)
169 pCtrlVideo
->attachVoutWindow( (*it
).pVoutWindow
,
170 (*it
).width
, (*it
).height
);
171 (*it
).pCtrlVideo
= pCtrlVideo
;
178 CtrlVideo
* VoutManager::getBestCtrlVideo( )
180 // try to find an unused useable VideoControl
182 vector
<CtrlVideo
*>::const_iterator it
;
183 for( it
= m_pCtrlVideoVec
.begin(); it
!= m_pCtrlVideoVec
.end(); it
++ )
185 if( (*it
)->isUseable() && !(*it
)->isUsed() )
195 void* VoutManager::acceptWnd( vout_window_t
* pWnd
)
197 int width
= (int)pWnd
->cfg
->width
;
198 int height
= (int)pWnd
->cfg
->height
;
200 // Creation of a dedicated Window per vout thread
201 VoutWindow
* pVoutWindow
= new VoutWindow( getIntf(), pWnd
, width
, height
,
202 (GenericWindow
*) m_pVoutMainWindow
);
204 void* handle
= pVoutWindow
->getOSHandle();
206 // try to find a video Control within the theme
207 CtrlVideo
* pCtrlVideo
= getBestCtrlVideo();
210 // A Video Control is available
211 // directly attach vout thread to it
212 pCtrlVideo
->attachVoutWindow( pVoutWindow
);
216 pVoutWindow
->setCtrlVideo( NULL
);
219 // save vout characteristics
220 m_SavedWndVec
.push_back( SavedWnd( pWnd
, pVoutWindow
, pCtrlVideo
) );
222 msg_Dbg( pWnd
, "New vout : handle = %p, Ctrl = %p, w x h = %dx%d",
223 handle
, pCtrlVideo
, width
, height
);
229 void VoutManager::releaseWnd( vout_window_t
*pWnd
)
231 // remove vout thread from savedVec
232 vector
<SavedWnd
>::iterator it
;
233 for( it
= m_SavedWndVec
.begin(); it
!= m_SavedWndVec
.end(); it
++ )
235 if( (*it
).pWnd
== pWnd
)
237 msg_Dbg( getIntf(), "vout released vout=%p, VideoCtrl=%p",
238 pWnd
, (*it
).pCtrlVideo
);
240 // if a video control was being used, detach from it
241 if( (*it
).pCtrlVideo
)
243 (*it
).pCtrlVideo
->detachVoutWindow( );
247 delete (*it
).pVoutWindow
;
248 m_SavedWndVec
.erase( it
);
255 void VoutManager::setSizeWnd( vout_window_t
*pWnd
, int width
, int height
)
257 msg_Dbg( pWnd
, "setSize (%dx%d) received from vout threadr",
260 vector
<SavedWnd
>::iterator it
;
261 for( it
= m_SavedWndVec
.begin(); it
!= m_SavedWndVec
.end(); it
++ )
263 if( (*it
).pWnd
== pWnd
)
265 VoutWindow
* pVoutWindow
= (*it
).pVoutWindow
;
267 pVoutWindow
->setOriginalWidth( width
);
268 pVoutWindow
->setOriginalHeight( height
);
270 CtrlVideo
* pCtrlVideo
= pVoutWindow
->getCtrlVideo();
273 pCtrlVideo
->resizeControl( width
, height
);
280 void VoutManager::setFullscreenWnd( vout_window_t
*pWnd
, bool b_fullscreen
)
282 msg_Dbg( pWnd
, "setFullscreen (%d) received from vout thread",
283 b_fullscreen
? 1 : 0 );
285 VlcProc::instance( getIntf() )->setFullscreenVar( b_fullscreen
);
289 m_pVoutMainWindow
->show();
293 m_pVoutMainWindow
->hide();
297 // Functions called by window provider
298 // ///////////////////////////////////
300 void *VoutManager::getWindow( intf_thread_t
*pIntf
, vout_window_t
*pWnd
)
302 // Theme may have been destroyed
303 if( !pIntf
->p_sys
->p_theme
)
306 vlc_mutex_lock( &pIntf
->p_sys
->vout_lock
);
307 pIntf
->p_sys
->b_vout_ready
= false;
308 pIntf
->p_sys
->handle
= NULL
;
310 CmdNewVoutWindow
*pCmd
=
311 new CmdNewVoutWindow( pIntf
, pWnd
);
313 AsyncQueue
*pQueue
= AsyncQueue::instance( pIntf
);
314 pQueue
->push( CmdGenericPtr( pCmd
), false );
316 while( !pIntf
->p_sys
->b_vout_ready
)
317 vlc_cond_wait( &pIntf
->p_sys
->vout_wait
, &pIntf
->p_sys
->vout_lock
);
319 void* handle
= pIntf
->p_sys
->handle
;
320 vlc_mutex_unlock( &pIntf
->p_sys
->vout_lock
);
326 void VoutManager::releaseWindow( intf_thread_t
*pIntf
, vout_window_t
*pWnd
)
328 vlc_mutex_lock( &pIntf
->p_sys
->vout_lock
);
329 pIntf
->p_sys
->b_vout_ready
= false;
331 CmdReleaseVoutWindow
*pCmd
=
332 new CmdReleaseVoutWindow( pIntf
, pWnd
);
334 AsyncQueue
*pQueue
= AsyncQueue::instance( pIntf
);
335 pQueue
->push( CmdGenericPtr( pCmd
), false );
337 while( !pIntf
->p_sys
->b_vout_ready
)
338 vlc_cond_wait( &pIntf
->p_sys
->vout_wait
, &pIntf
->p_sys
->vout_lock
);
340 vlc_mutex_unlock( &pIntf
->p_sys
->vout_lock
);
344 int VoutManager::controlWindow( struct vout_window_t
*pWnd
,
345 int query
, va_list args
)
347 intf_thread_t
*pIntf
= (intf_thread_t
*)pWnd
->sys
;
348 VoutManager
*pThis
= pIntf
->p_sys
->p_voutManager
;
352 case VOUT_WINDOW_SET_SIZE
:
354 unsigned int i_width
= va_arg( args
, unsigned int );
355 unsigned int i_height
= va_arg( args
, unsigned int );
357 if( i_width
&& i_height
)
359 // Post a vout resize command
360 CmdResizeVout
*pCmd
=
361 new CmdResizeVout( pThis
->getIntf(),
362 pWnd
, (int)i_width
, (int)i_height
);
364 AsyncQueue::instance( pThis
->getIntf() );
365 pQueue
->push( CmdGenericPtr( pCmd
) );
370 case VOUT_WINDOW_SET_FULLSCREEN
:
372 bool b_fullscreen
= va_arg( args
, int );
374 // Post a vout resize command
375 CmdSetFullscreen
* pCmd
=
376 new CmdSetFullscreen( pThis
->getIntf(), pWnd
, b_fullscreen
);
378 AsyncQueue
*pQueue
= AsyncQueue::instance( pThis
->getIntf() );
379 pQueue
->push( CmdGenericPtr( pCmd
) );
384 case VOUT_WINDOW_SET_STATE
:
386 unsigned i_arg
= va_arg( args
, unsigned );
387 unsigned on_top
= i_arg
& VOUT_WINDOW_STATE_ABOVE
;
389 // Post a SetOnTop command
391 new CmdSetOnTop( pThis
->getIntf(), on_top
);
393 AsyncQueue
*pQueue
= AsyncQueue::instance( pThis
->getIntf() );
394 pQueue
->push( CmdGenericPtr( pCmd
) );
401 msg_Dbg( pWnd
, "control query not supported" );