skins2: fix RadialSlider
[vlc/asuraparaju-public.git] / modules / gui / skins2 / src / vout_manager.cpp
blob86bd5e1e9c530ab7eaabb993e77c5927239db6f4
1 /*****************************************************************************
2 * vout_manager.cpp
3 *****************************************************************************
4 * Copyright (C) 2009 the VideoLAN team
5 * $Id$
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 *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
28 #include <vlc_vout.h>
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 )
89 m_pFscWindow = 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 )
124 if( !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();
135 if( pCtrlVideo )
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;
156 break;
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;
172 break;
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() )
187 return (*it);
191 return NULL;
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();
208 if( pCtrlVideo )
210 // A Video Control is available
211 // directly attach vout thread to it
212 pCtrlVideo->attachVoutWindow( pVoutWindow );
214 else
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 );
225 return handle;
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( );
246 // remove resources
247 delete (*it).pVoutWindow;
248 m_SavedWndVec.erase( it );
249 break;
255 void VoutManager::setSizeWnd( vout_window_t *pWnd, int width, int height )
257 msg_Dbg( pWnd, "setSize (%dx%d) received from vout threadr",
258 width, height );
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();
271 if( pCtrlVideo )
273 pCtrlVideo->resizeControl( width, height );
275 break;
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 );
287 if( b_fullscreen )
289 m_pVoutMainWindow->show();
291 else
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 )
304 return NULL;
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 );
322 return handle;
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;
350 switch( query )
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 );
363 AsyncQueue *pQueue =
364 AsyncQueue::instance( pThis->getIntf() );
365 pQueue->push( CmdGenericPtr( pCmd ) );
367 return VLC_EGENERIC;
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 ) );
381 return VLC_SUCCESS;
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
390 CmdSetOnTop* pCmd =
391 new CmdSetOnTop( pThis->getIntf(), on_top );
393 AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
394 pQueue->push( CmdGenericPtr( pCmd ) );
396 return VLC_SUCCESS;
400 default:
401 msg_Dbg( pWnd, "control query not supported" );
402 return VLC_EGENERIC;