]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/vlcproc.cpp
* skins2/src/vlcproc.cpp: New "dvd.isActive" boolean variable
[vlc] / modules / gui / skins2 / src / vlcproc.cpp
1 /*****************************************************************************
2  * vlcproc.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teuli�e <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 #include <vlc/aout.h>
26 #include <vlc/vout.h>
27 #include <aout_internal.h>
28
29 #include "vlcproc.hpp"
30 #include "os_factory.hpp"
31 #include "os_timer.hpp"
32 #include "var_manager.hpp"
33 #include "theme.hpp"
34 #include "window_manager.hpp"
35 #include "../commands/async_queue.hpp"
36 #include "../commands/cmd_change_skin.hpp"
37 #include "../commands/cmd_show_window.hpp"
38 #include "../commands/cmd_quit.hpp"
39 #include "../commands/cmd_resize.hpp"
40 #include "../commands/cmd_vars.hpp"
41 #include "../commands/cmd_dialogs.hpp"
42 #include "../utils/var_bool.hpp"
43 #include <sstream>
44
45
46 VlcProc *VlcProc::instance( intf_thread_t *pIntf )
47 {
48     if( pIntf->p_sys->p_vlcProc == NULL )
49     {
50         pIntf->p_sys->p_vlcProc = new VlcProc( pIntf );
51     }
52
53     return pIntf->p_sys->p_vlcProc;
54 }
55
56
57 void VlcProc::destroy( intf_thread_t *pIntf )
58 {
59     if( pIntf->p_sys->p_vlcProc )
60     {
61         delete pIntf->p_sys->p_vlcProc;
62         pIntf->p_sys->p_vlcProc = NULL;
63     }
64 }
65
66
67 VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ),
68     m_varVoutSize( pIntf ), m_varEqBands( pIntf ),
69     m_pVout( NULL ), m_pAout( NULL ), m_cmdManage( this )
70 {
71     // Create a timer to poll the status of the vlc
72     OSFactory *pOsFactory = OSFactory::instance( pIntf );
73     m_pTimer = pOsFactory->createOSTimer( m_cmdManage );
74     m_pTimer->start( 100, false );
75
76     // Create and register VLC variables
77     VarManager *pVarManager = VarManager::instance( getIntf() );
78
79 #define REGISTER_VAR( var, type, name ) \
80     var = VariablePtr( new type( getIntf() ) ); \
81     pVarManager->registerVar( var, name );
82     REGISTER_VAR( m_cPlaylist, Playlist, "playlist" )
83     pVarManager->registerVar( getPlaylistVar().getPositionVarPtr(),
84                               "playlist.slider" );
85     REGISTER_VAR( m_cVarRandom, VarBoolImpl, "playlist.isRandom" )
86     REGISTER_VAR( m_cVarLoop, VarBoolImpl, "playlist.isLoop" )
87     REGISTER_VAR( m_cVarRepeat, VarBoolImpl, "playlist.isRepeat" )
88     REGISTER_VAR( m_cPlaytree, Playtree, "playtree" )
89     pVarManager->registerVar( getPlaytreeVar().getPositionVarPtr(),
90                               "playtree.slider" );
91     pVarManager->registerVar( m_cVarRandom, "playtree.isRandom" );
92     pVarManager->registerVar( m_cVarLoop, "playtree.isLoop" );
93     pVarManager->registerVar( m_cVarRepeat, "playtree.isRepeat" );
94     REGISTER_VAR( m_cVarTime, StreamTime, "time" )
95     REGISTER_VAR( m_cVarVolume, Volume, "volume" )
96     REGISTER_VAR( m_cVarMute, VarBoolImpl, "vlc.isMute" )
97     REGISTER_VAR( m_cVarPlaying, VarBoolImpl, "vlc.isPlaying" )
98     REGISTER_VAR( m_cVarStopped, VarBoolImpl, "vlc.isStopped" )
99     REGISTER_VAR( m_cVarPaused, VarBoolImpl, "vlc.isPaused" )
100     REGISTER_VAR( m_cVarSeekable, VarBoolImpl, "vlc.isSeekable" )
101     REGISTER_VAR( m_cVarEqualizer, VarBoolImpl, "equalizer.isEnabled" )
102     REGISTER_VAR( m_cVarEqPreamp, EqualizerPreamp, "equalizer.preamp" )
103     REGISTER_VAR( m_cVarDvdActive, VarBoolImpl, "dvd.isActive" )
104 #undef REGISTER_VAR
105     m_cVarStreamName = VariablePtr( new VarText( getIntf(), false ) );
106     pVarManager->registerVar( m_cVarStreamName, "streamName" );
107     m_cVarStreamURI = VariablePtr( new VarText( getIntf(), false ) );
108     pVarManager->registerVar( m_cVarStreamURI, "streamURI" );
109
110     // Register the equalizer bands
111     for( int i = 0; i < EqualizerBands::kNbBands; i++)
112     {
113         stringstream ss;
114         ss << "equalizer.band(" << i << ")";
115         pVarManager->registerVar( m_varEqBands.getBand( i ), ss.str() );
116     }
117
118     // XXX WARNING XXX
119     // The object variable callbacks are called from other VLC threads,
120     // so they must put commands in the queue and NOT do anything else
121     // (X11 calls are not reentrant)
122
123     // Called when the playlist changes
124     var_AddCallback( pIntf->p_sys->p_playlist, "intf-change",
125                      onIntfChange, this );
126     // Called when a playlist item is added
127     var_AddCallback( pIntf->p_sys->p_playlist, "item-append",
128                      onItemAppend, this );
129     // Called when a playlist item is deleted
130     // TODO: properly handle item-deleted
131     var_AddCallback( pIntf->p_sys->p_playlist, "item-deleted",
132                      onItemDelete, this );
133     // Called when the "interface shower" wants us to show the skin
134     var_AddCallback( pIntf->p_sys->p_playlist, "intf-show",
135                      onIntfShow, this );
136     // Called when the current played item changes
137     var_AddCallback( pIntf->p_sys->p_playlist, "playlist-current",
138                      onPlaylistChange, this );
139     // Called when a playlist item changed
140     var_AddCallback( pIntf->p_sys->p_playlist, "item-change",
141                      onItemChange, this );
142     // Called when our skins2 demux wants us to load a new skin
143     var_AddCallback( pIntf, "skin-to-load", onSkinToLoad, this );
144
145     // Called when we have an interaction dialog to display
146     var_Create( pIntf, "interaction", VLC_VAR_ADDRESS );
147     var_AddCallback( pIntf, "interaction", onInteraction, this );
148     pIntf->b_interaction = VLC_TRUE;
149
150     // Callbacks for vout requests
151     getIntf()->pf_request_window = &getWindow;
152     getIntf()->pf_release_window = &releaseWindow;
153     getIntf()->pf_control_window = &controlWindow;
154
155     getIntf()->p_sys->p_input = NULL;
156 }
157
158
159 VlcProc::~VlcProc()
160 {
161     m_pTimer->stop();
162     delete( m_pTimer );
163     if( getIntf()->p_sys->p_input )
164     {
165         vlc_object_release( getIntf()->p_sys->p_input );
166     }
167
168     // Callbacks for vout requests
169     getIntf()->pf_request_window = NULL;
170     getIntf()->pf_release_window = NULL;
171     getIntf()->pf_control_window = NULL;
172
173     var_DelCallback( getIntf()->p_sys->p_playlist, "intf-change",
174                      onIntfChange, this );
175     var_DelCallback( getIntf()->p_sys->p_playlist, "item-append",
176                      onItemAppend, this );
177     var_DelCallback( getIntf()->p_sys->p_playlist, "item-deleted",
178                      onItemDelete, this );
179     var_DelCallback( getIntf()->p_sys->p_playlist, "intf-show",
180                      onIntfShow, this );
181     var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-current",
182                      onPlaylistChange, this );
183     var_DelCallback( getIntf()->p_sys->p_playlist, "item-change",
184                      onItemChange, this );
185     var_DelCallback( getIntf(), "skin-to-load", onSkinToLoad, this );
186 }
187
188
189 void VlcProc::registerVoutWindow( void *pVoutWindow )
190 {
191     m_handleSet.insert( pVoutWindow );
192     // Reparent the vout window
193     if( m_pVout )
194     {
195         if( vout_Control( m_pVout, VOUT_REPARENT ) != VLC_SUCCESS )
196             vout_Control( m_pVout, VOUT_CLOSE );
197     }
198 }
199
200
201 void VlcProc::unregisterVoutWindow( void *pVoutWindow )
202 {
203     m_handleSet.erase( pVoutWindow );
204 }
205
206
207 void VlcProc::dropVout()
208 {
209     if( m_pVout )
210     {
211         if( vout_Control( m_pVout, VOUT_REPARENT ) != VLC_SUCCESS )
212             vout_Control( m_pVout, VOUT_CLOSE );
213         m_pVout = NULL;
214     }
215 }
216
217
218 void VlcProc::manage()
219 {
220     // Did the user requested to quit vlc ?
221     if( getIntf()->b_die || getIntf()->p_vlc->b_die )
222     {
223         CmdQuit *pCmd = new CmdQuit( getIntf() );
224         AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
225         pQueue->push( CmdGenericPtr( pCmd ) );
226     }
227
228     // Get the VLC variables
229     StreamTime *pTime = (StreamTime*)m_cVarTime.get();
230     VarBoolImpl *pVarPlaying = (VarBoolImpl*)m_cVarPlaying.get();
231     VarBoolImpl *pVarStopped = (VarBoolImpl*)m_cVarStopped.get();
232     VarBoolImpl *pVarPaused = (VarBoolImpl*)m_cVarPaused.get();
233     VarBoolImpl *pVarSeekable = (VarBoolImpl*)m_cVarSeekable.get();
234     VarBoolImpl *pVarRandom = (VarBoolImpl*)m_cVarRandom.get();
235     VarBoolImpl *pVarLoop = (VarBoolImpl*)m_cVarLoop.get();
236     VarBoolImpl *pVarRepeat = (VarBoolImpl*)m_cVarRepeat.get();
237     VarBoolImpl *pVarDvdActive = (VarBoolImpl*)m_cVarDvdActive.get();
238
239     // Refresh audio variables
240     refreshAudio();
241
242    // Update the input
243     if( getIntf()->p_sys->p_input == NULL )
244     {
245         getIntf()->p_sys->p_input = getIntf()->p_sys->p_playlist->p_input;
246         if( getIntf()->p_sys->p_input )
247             vlc_object_yield( getIntf()->p_sys->p_input );
248     }
249     else if( getIntf()->p_sys->p_input->b_dead )
250     {
251         vlc_object_release( getIntf()->p_sys->p_input );
252         getIntf()->p_sys->p_input = NULL;
253     }
254
255     input_thread_t *pInput = getIntf()->p_sys->p_input;
256
257     if( pInput && !pInput->b_die )
258     {
259         // Refresh time variables
260         vlc_value_t pos;
261         var_Get( pInput, "position", &pos );
262         pTime->set( pos.f_float, false );
263
264         // Get the status of the playlist
265         playlist_status_t status =
266             getIntf()->p_sys->p_playlist->status.i_status;
267
268         pVarPlaying->set( status == PLAYLIST_RUNNING );
269         pVarStopped->set( status == PLAYLIST_STOPPED );
270         pVarPaused->set( status == PLAYLIST_PAUSED );
271
272         pVarSeekable->set( pos.f_float != 0.0 );
273
274         // Refresh DVD detection
275         vlc_value_t chapters_count;
276         var_Change( pInput, "chapter", VLC_VAR_CHOICESCOUNT,
277                     &chapters_count, NULL );
278         pVarDvdActive->set( chapters_count.i_int > 0 );
279     }
280     else
281     {
282         pVarPlaying->set( false );
283         pVarPaused->set( false );
284         pVarStopped->set( true );
285         pVarSeekable->set( false );
286         pVarDvdActive->set( false );
287         pTime->set( 0, false );
288     }
289
290     // Refresh the random variable
291     vlc_value_t val;
292     var_Get( getIntf()->p_sys->p_playlist, "random", &val );
293     pVarRandom->set( val.b_bool != 0 );
294
295     // Refresh the loop variable
296     var_Get( getIntf()->p_sys->p_playlist, "loop", &val );
297     pVarLoop->set( val.b_bool != 0 );
298
299     // Refresh the repeat variable
300     var_Get( getIntf()->p_sys->p_playlist, "repeat", &val );
301     pVarRepeat->set( val.b_bool != 0 );
302 }
303
304
305 void VlcProc::CmdManage::execute()
306 {
307     // Just forward to VlcProc
308     m_pParent->manage();
309 }
310
311
312 void VlcProc::refreshAudio()
313 {
314     char *pFilters = NULL;
315
316     // Check if the audio output has changed
317     aout_instance_t *pAout = (aout_instance_t *)vlc_object_find( getIntf(),
318             VLC_OBJECT_AOUT, FIND_ANYWHERE );
319     if( pAout )
320     {
321         if( pAout != m_pAout )
322         {
323             // Register the equalizer callbacks
324             if( !var_AddCallback( pAout, "equalizer-bands",
325                                   onEqBandsChange, this ) &&
326                 !var_AddCallback( pAout, "equalizer-preamp",
327                                   onEqPreampChange, this ) )
328             {
329                 m_pAout = pAout;
330                 //char * psz_bands = var_GetString( p_aout, "equalizer-bands" );
331             }
332         }
333         // Get the audio filters
334         pFilters = var_GetString( pAout, "audio-filter" );
335         vlc_object_release( pAout );
336     }
337     else
338     {
339         // Get the audio filters
340         pFilters = config_GetPsz( getIntf(), "audio-filter" );
341     }
342
343     // Refresh sound volume
344     audio_volume_t volume;
345     aout_VolumeGet( getIntf(), &volume );
346     Volume *pVolume = (Volume*)m_cVarVolume.get();
347     pVolume->set( (double)volume * 2.0 / AOUT_VOLUME_MAX );
348
349     // Set the mute variable
350     VarBoolImpl *pVarMute = (VarBoolImpl*)m_cVarMute.get();
351     pVarMute->set( volume == 0 );
352
353     // Refresh the equalizer variable
354     VarBoolImpl *pVarEqualizer = (VarBoolImpl*)m_cVarEqualizer.get();
355     pVarEqualizer->set( pFilters && strstr( pFilters, "equalizer" ) );
356 }
357
358
359 int VlcProc::onIntfChange( vlc_object_t *pObj, const char *pVariable,
360                            vlc_value_t oldVal, vlc_value_t newVal,
361                            void *pParam )
362 {
363     VlcProc *pThis = (VlcProc*)pParam;
364
365     // Update the stream variable
366     playlist_t *p_playlist = (playlist_t*)pObj;
367     pThis->updateStreamName(p_playlist);
368
369     // Create a playlist notify command (for old style playlist)
370     CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
371     // Create a playtree notify command (for new style playtree)
372     CmdPlaytreeChanged *pCmdTree = new CmdPlaytreeChanged( pThis->getIntf() );
373
374     // Push the command in the asynchronous command queue
375     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
376     pQueue->push( CmdGenericPtr( pCmd ) );
377     pQueue->push( CmdGenericPtr( pCmdTree ) );
378
379     return VLC_SUCCESS;
380 }
381
382
383 int VlcProc::onIntfShow( vlc_object_t *pObj, const char *pVariable,
384                          vlc_value_t oldVal, vlc_value_t newVal,
385                          void *pParam )
386 {
387     if (newVal.i_int)
388     {
389         VlcProc *pThis = (VlcProc*)pParam;
390
391         // Create a raise all command
392         CmdRaiseAll *pCmd = new CmdRaiseAll( pThis->getIntf(),
393             pThis->getIntf()->p_sys->p_theme->getWindowManager() );
394
395         // Push the command in the asynchronous command queue
396         AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
397         pQueue->push( CmdGenericPtr( pCmd ) );
398     }
399
400     return VLC_SUCCESS;
401 }
402
403
404 int VlcProc::onItemChange( vlc_object_t *pObj, const char *pVariable,
405                            vlc_value_t oldVal, vlc_value_t newVal,
406                            void *pParam )
407 {
408     VlcProc *pThis = (VlcProc*)pParam;
409
410     // Update the stream variable
411     playlist_t *p_playlist = (playlist_t*)pObj;
412     pThis->updateStreamName(p_playlist);
413
414     // Create a playlist notify command
415     // TODO: selective update
416     CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
417     // Create a playtree notify command
418     CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
419                                                          newVal.i_int );
420
421     // Push the command in the asynchronous command queue
422     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
423     pQueue->push( CmdGenericPtr( pCmd ) );
424     pQueue->push( CmdGenericPtr( pCmdTree ), true );
425
426     return VLC_SUCCESS;
427 }
428
429 int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable,
430                            vlc_value_t oldVal, vlc_value_t newVal,
431                            void *pParam )
432 {
433     VlcProc *pThis = (VlcProc*)pParam;
434
435     playlist_add_t *p_add = (playlist_add_t*)malloc( sizeof(
436                                                 playlist_add_t ) ) ;
437
438     memcpy( p_add, newVal.p_address, sizeof( playlist_add_t ) ) ;
439
440     CmdGenericPtr ptrTree;
441     CmdPlaytreeAppend *pCmdTree = new CmdPlaytreeAppend( pThis->getIntf(),
442                                                              p_add );
443     ptrTree = CmdGenericPtr( pCmdTree );
444
445     // Create a playlist notify command (for old style playlist)
446     CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
447
448     // Push the command in the asynchronous command queue
449     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
450     pQueue->push( CmdGenericPtr( pCmd ) );
451     pQueue->push( ptrTree , false );
452
453     return VLC_SUCCESS;
454 }
455
456 int VlcProc::onItemDelete( vlc_object_t *pObj, const char *pVariable,
457                            vlc_value_t oldVal, vlc_value_t newVal,
458                            void *pParam )
459 {
460     VlcProc *pThis = (VlcProc*)pParam;
461
462     int i_id = newVal.i_int;
463
464     CmdGenericPtr ptrTree;
465     CmdPlaytreeDelete *pCmdTree = new CmdPlaytreeDelete( pThis->getIntf(),
466                                                          i_id);
467     ptrTree = CmdGenericPtr( pCmdTree );
468
469     // Create a playlist notify command (for old style playlist)
470     CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
471
472     // Push the command in the asynchronous command queue
473     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
474     pQueue->push( CmdGenericPtr( pCmd ) );
475     pQueue->push( ptrTree , false );
476
477     return VLC_SUCCESS;
478 }
479
480
481
482
483 int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
484                                vlc_value_t oldVal, vlc_value_t newVal,
485                                void *pParam )
486 {
487     VlcProc *pThis = (VlcProc*)pParam;
488
489     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
490
491     // Update the stream variable
492     playlist_t *p_playlist = (playlist_t*)pObj;
493     pThis->updateStreamName(p_playlist);
494
495     // Create a playlist notify command (old style playlist)
496     // TODO: selective update
497     CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
498     pQueue->push( CmdGenericPtr( pCmd ) );
499     // Create two playtree notify commands: one for old item, one for new
500     CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
501                                                          oldVal.i_int );
502     pQueue->push( CmdGenericPtr( pCmdTree ) , true );
503     pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(), newVal.i_int );
504     pQueue->push( CmdGenericPtr( pCmdTree ) , true );
505
506     return VLC_SUCCESS;
507 }
508
509
510 int VlcProc::onSkinToLoad( vlc_object_t *pObj, const char *pVariable,
511                            vlc_value_t oldVal, vlc_value_t newVal,
512                            void *pParam )
513 {
514     VlcProc *pThis = (VlcProc*)pParam;
515
516     // Create a playlist notify command
517     CmdChangeSkin *pCmd =
518         new CmdChangeSkin( pThis->getIntf(), newVal.psz_string );
519
520     // Push the command in the asynchronous command queue
521     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
522     pQueue->push( CmdGenericPtr( pCmd ) );
523
524     return VLC_SUCCESS;
525 }
526
527 int VlcProc::onInteraction( vlc_object_t *pObj, const char *pVariable,
528                             vlc_value_t oldVal, vlc_value_t newVal,
529                             void *pParam )
530 {
531     VlcProc *pThis = (VlcProc*)pParam;
532     interaction_dialog_t *p_dialog = (interaction_dialog_t *)(newVal.p_address);
533
534     CmdInteraction *pCmd = new CmdInteraction( pThis->getIntf(), p_dialog );
535     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
536     pQueue->push( CmdGenericPtr( pCmd ) );
537     return VLC_SUCCESS;
538 }
539
540
541 void VlcProc::updateStreamName( playlist_t *p_playlist )
542 {
543     if( p_playlist->p_input )
544     {
545         VarText &rStreamName = getStreamNameVar();
546         VarText &rStreamURI = getStreamURIVar();
547         // XXX: we should not need to access p_input->psz_source directly, a
548         // getter should be provided by VLC core
549         string name = p_playlist->p_input->input.p_item->psz_name;
550         // XXX: This should be done in VLC core, not here...
551         // Remove path information if any
552         OSFactory *pFactory = OSFactory::instance( getIntf() );
553         string::size_type pos = name.rfind( pFactory->getDirSeparator() );
554         if( pos != string::npos )
555         {
556             name = name.substr( pos + 1, name.size() - pos + 1 );
557         }
558         UString srcName( getIntf(), name.c_str() );
559         UString srcURI( getIntf(),
560                          p_playlist->p_input->input.p_item->psz_uri );
561
562         // Create commands to update the stream variables
563         CmdSetText *pCmd1 = new CmdSetText( getIntf(), rStreamName, srcName );
564         CmdSetText *pCmd2 = new CmdSetText( getIntf(), rStreamURI, srcURI );
565         // Push the commands in the asynchronous command queue
566         AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
567         pQueue->push( CmdGenericPtr( pCmd1 ), false );
568         pQueue->push( CmdGenericPtr( pCmd2 ), false );
569     }
570 }
571
572
573 void *VlcProc::getWindow( intf_thread_t *pIntf, vout_thread_t *pVout,
574                           int *pXHint, int *pYHint,
575                           unsigned int *pWidthHint,
576                           unsigned int *pHeightHint )
577 {
578     VlcProc *pThis = pIntf->p_sys->p_vlcProc;
579     pThis->m_pVout = pVout;
580     if( pThis->m_handleSet.empty() )
581     {
582         return NULL;
583     }
584     else
585     {
586         // Get the window handle
587         void *pWindow = *pThis->m_handleSet.begin();
588         // Post a resize vout command
589         CmdResizeVout *pCmd = new CmdResizeVout( pThis->getIntf(), pWindow,
590                                                  *pWidthHint, *pHeightHint );
591         AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
592         pQueue->push( CmdGenericPtr( pCmd ) );
593         return pWindow;
594     }
595 }
596
597
598 void VlcProc::releaseWindow( intf_thread_t *pIntf, void *pWindow )
599 {
600     VlcProc *pThis = pIntf->p_sys->p_vlcProc;
601     pThis->m_pVout = NULL;
602 }
603
604
605 int VlcProc::controlWindow( intf_thread_t *pIntf, void *pWindow,
606                             int query, va_list args )
607 {
608     VlcProc *pThis = pIntf->p_sys->p_vlcProc;
609
610     switch( query )
611     {
612         case VOUT_SET_SIZE:
613         {
614             if( pThis->m_pVout )
615             {
616                 unsigned int i_width  = va_arg( args, unsigned int );
617                 unsigned int i_height = va_arg( args, unsigned int );
618                 if( !i_width ) i_width = pThis->m_pVout->i_window_width;
619                 if( !i_height ) i_height = pThis->m_pVout->i_window_height;
620
621                 // Post a resize vout command
622                 CmdResizeVout *pCmd =
623                     new CmdResizeVout( pThis->getIntf(), pWindow,
624                                        i_width, i_height );
625                 AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
626                 pQueue->push( CmdGenericPtr( pCmd ) );
627             }
628         }
629
630         default:
631             msg_Dbg( pIntf, "control query not supported" );
632             break;
633     }
634
635     return VLC_SUCCESS;
636 }
637
638
639 int VlcProc::onEqBandsChange( vlc_object_t *pObj, const char *pVariable,
640                               vlc_value_t oldVal, vlc_value_t newVal,
641                               void *pParam )
642 {
643     VlcProc *pThis = (VlcProc*)pParam;
644
645     // Post a set equalizer bands command
646     CmdSetEqBands *pCmd = new CmdSetEqBands( pThis->getIntf(),
647                                              pThis->m_varEqBands,
648                                              newVal.psz_string );
649     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
650     pQueue->push( CmdGenericPtr( pCmd ) );
651
652     return VLC_SUCCESS;
653 }
654
655
656 int VlcProc::onEqPreampChange( vlc_object_t *pObj, const char *pVariable,
657                                vlc_value_t oldVal, vlc_value_t newVal,
658                                void *pParam )
659 {
660     VlcProc *pThis = (VlcProc*)pParam;
661     EqualizerPreamp *pVarPreamp = (EqualizerPreamp*)(pThis->m_cVarEqPreamp.get());
662
663     // Post a set preamp command
664     CmdSetEqPreamp *pCmd = new CmdSetEqPreamp( pThis->getIntf(), *pVarPreamp,
665                                               (newVal.f_float + 20.0) / 40.0 );
666     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
667     pQueue->push( CmdGenericPtr( pCmd ) );
668
669     return VLC_SUCCESS;
670 }
671