]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/vlcproc.cpp
Skins: set the maximum volume to 1024, not 512
[vlc] / modules / gui / skins2 / src / vlcproc.cpp
1 /*****************************************************************************
2  * vlcproc.cpp
3  *****************************************************************************
4  * Copyright (C) 2003-2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@via.ecp.fr>
9  *          Erwan Tulou      <erwan10@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <vlc_common.h>
31 #include <vlc_aout.h>
32 #include <vlc_vout.h>
33 #include <vlc_playlist.h>
34
35 #include "vlcproc.hpp"
36 #include "os_factory.hpp"
37 #include "os_loop.hpp"
38 #include "os_timer.hpp"
39 #include "var_manager.hpp"
40 #include "vout_manager.hpp"
41 #include "theme.hpp"
42 #include "window_manager.hpp"
43 #include "../commands/async_queue.hpp"
44 #include "../commands/cmd_change_skin.hpp"
45 #include "../commands/cmd_show_window.hpp"
46 #include "../commands/cmd_quit.hpp"
47 #include "../commands/cmd_resize.hpp"
48 #include "../commands/cmd_vars.hpp"
49 #include "../commands/cmd_dialogs.hpp"
50 #include "../commands/cmd_update_item.hpp"
51 #include "../commands/cmd_audio.hpp"
52 #include "../commands/cmd_callbacks.hpp"
53 #include "../utils/var_bool.hpp"
54 #include <sstream>
55
56 #include <assert.h>
57
58 VlcProc *VlcProc::instance( intf_thread_t *pIntf )
59 {
60     if( pIntf->p_sys->p_vlcProc == NULL )
61     {
62         pIntf->p_sys->p_vlcProc = new VlcProc( pIntf );
63     }
64
65     return pIntf->p_sys->p_vlcProc;
66 }
67
68
69 void VlcProc::destroy( intf_thread_t *pIntf )
70 {
71     delete pIntf->p_sys->p_vlcProc;
72     pIntf->p_sys->p_vlcProc = NULL;
73 }
74
75
76 VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ),
77     m_varVoutSize( pIntf ), m_varEqBands( pIntf ),
78     m_pVout( NULL ), m_pAout( NULL ), m_bEqualizer_started( false ),
79     m_cmdManage( this )
80 {
81     // Create a timer to poll the status of the vlc
82     OSFactory *pOsFactory = OSFactory::instance( pIntf );
83     m_pTimer = pOsFactory->createOSTimer( m_cmdManage );
84     m_pTimer->start( 100, false );
85
86     // Create and register VLC variables
87     VarManager *pVarManager = VarManager::instance( getIntf() );
88
89 #define REGISTER_VAR( var, type, name ) \
90     var = VariablePtr( new type( getIntf() ) ); \
91     pVarManager->registerVar( var, name );
92     REGISTER_VAR( m_cVarRandom, VarBoolImpl, "playlist.isRandom" )
93     REGISTER_VAR( m_cVarLoop, VarBoolImpl, "playlist.isLoop" )
94     REGISTER_VAR( m_cVarRepeat, VarBoolImpl, "playlist.isRepeat" )
95     REGISTER_VAR( m_cPlaytree, Playtree, "playtree" )
96     pVarManager->registerVar( getPlaytreeVar().getPositionVarPtr(),
97                               "playtree.slider" );
98     pVarManager->registerVar( m_cVarRandom, "playtree.isRandom" );
99     pVarManager->registerVar( m_cVarLoop, "playtree.isLoop" );
100
101     REGISTER_VAR( m_cVarPlaying, VarBoolImpl, "vlc.isPlaying" )
102     REGISTER_VAR( m_cVarStopped, VarBoolImpl, "vlc.isStopped" )
103     REGISTER_VAR( m_cVarPaused, VarBoolImpl, "vlc.isPaused" )
104
105     /* Input variables */
106     pVarManager->registerVar( m_cVarRepeat, "playtree.isRepeat" );
107     REGISTER_VAR( m_cVarTime, StreamTime, "time" )
108     REGISTER_VAR( m_cVarSeekable, VarBoolImpl, "vlc.isSeekable" )
109     REGISTER_VAR( m_cVarDvdActive, VarBoolImpl, "dvd.isActive" )
110
111     REGISTER_VAR( m_cVarRecordable, VarBoolImpl, "vlc.canRecord" )
112     REGISTER_VAR( m_cVarRecording, VarBoolImpl, "vlc.isRecording" )
113
114     /* Vout variables */
115     REGISTER_VAR( m_cVarFullscreen, VarBoolImpl, "vlc.isFullscreen" )
116     REGISTER_VAR( m_cVarHasVout, VarBoolImpl, "vlc.hasVout" )
117
118     /* Aout variables */
119     REGISTER_VAR( m_cVarHasAudio, VarBoolImpl, "vlc.hasAudio" )
120     REGISTER_VAR( m_cVarVolume, Volume, "volume" )
121     REGISTER_VAR( m_cVarMute, VarBoolImpl, "vlc.isMute" )
122     REGISTER_VAR( m_cVarEqualizer, VarBoolImpl, "equalizer.isEnabled" )
123     REGISTER_VAR( m_cVarEqPreamp, EqualizerPreamp, "equalizer.preamp" )
124
125 #undef REGISTER_VAR
126     m_cVarStreamName = VariablePtr( new VarText( getIntf(), false ) );
127     pVarManager->registerVar( m_cVarStreamName, "streamName" );
128     m_cVarStreamURI = VariablePtr( new VarText( getIntf(), false ) );
129     pVarManager->registerVar( m_cVarStreamURI, "streamURI" );
130     m_cVarStreamBitRate = VariablePtr( new VarText( getIntf(), false ) );
131     pVarManager->registerVar( m_cVarStreamBitRate, "bitrate" );
132     m_cVarStreamSampleRate = VariablePtr( new VarText( getIntf(), false ) );
133     pVarManager->registerVar( m_cVarStreamSampleRate, "samplerate" );
134
135     // Register the equalizer bands
136     for( int i = 0; i < EqualizerBands::kNbBands; i++)
137     {
138         stringstream ss;
139         ss << "equalizer.band(" << i << ")";
140         pVarManager->registerVar( m_varEqBands.getBand( i ), ss.str() );
141     }
142
143     // XXX WARNING XXX
144     // The object variable callbacks are called from other VLC threads,
145     // so they must put commands in the queue and NOT do anything else
146     // (X11 calls are not reentrant)
147
148 #define ADD_CALLBACK( p_object, var ) \
149     var_AddCallback( p_object, var, onGenericCallback, this );
150
151     ADD_CALLBACK( pIntf->p_libvlc, "volume-change" )
152     ADD_CALLBACK( pIntf->p_libvlc, "intf-show" )
153
154     ADD_CALLBACK( pIntf->p_sys->p_playlist, "item-current" )
155     ADD_CALLBACK( pIntf->p_sys->p_playlist, "random" )
156     ADD_CALLBACK( pIntf->p_sys->p_playlist, "loop" )
157     ADD_CALLBACK( pIntf->p_sys->p_playlist, "repeat" )
158
159 #undef ADD_CALLBACK
160
161     // Called when the playlist changes
162     var_AddCallback( pIntf->p_sys->p_playlist, "intf-change",
163                      onIntfChange, this );
164     // Called when a playlist item is added
165     var_AddCallback( pIntf->p_sys->p_playlist, "playlist-item-append",
166                      onItemAppend, this );
167     // Called when a playlist item is deleted
168     // TODO: properly handle item-deleted
169     var_AddCallback( pIntf->p_sys->p_playlist, "playlist-item-deleted",
170                      onItemDelete, this );
171     // Called when the current input changes
172     var_AddCallback( pIntf->p_sys->p_playlist, "input-current",
173                      onInputNew, this );
174     // Called when a playlist item changed
175     var_AddCallback( pIntf->p_sys->p_playlist, "item-change",
176                      onItemChange, this );
177     // Called when our skins2 demux wants us to load a new skin
178     var_AddCallback( pIntf, "skin-to-load", onSkinToLoad, this );
179
180     // Called when we have an interaction dialog to display
181     var_Create( pIntf, "interaction", VLC_VAR_ADDRESS );
182     var_AddCallback( pIntf, "interaction", onInteraction, this );
183     interaction_Register( pIntf );
184
185     // initialize variables refering to liblvc and playlist objects
186     init_variables();
187 }
188
189
190 VlcProc::~VlcProc()
191 {
192     m_pTimer->stop();
193     delete( m_pTimer );
194
195     if( m_pAout )
196     {
197         vlc_object_release( m_pAout );
198         m_pAout = NULL;
199     }
200     if( m_pVout )
201     {
202         vlc_object_release( m_pVout );
203         m_pVout = NULL;
204     }
205
206     interaction_Unregister( getIntf() );
207
208     var_DelCallback( getIntf()->p_libvlc, "volume-change",
209                      onGenericCallback, this );
210     var_DelCallback( getIntf()->p_libvlc, "intf-show",
211                      onGenericCallback, this );
212
213     var_DelCallback( getIntf()->p_sys->p_playlist, "item-current",
214                      onGenericCallback, this );
215     var_DelCallback( getIntf()->p_sys->p_playlist, "random",
216                      onGenericCallback, this );
217     var_DelCallback( getIntf()->p_sys->p_playlist, "loop",
218                      onGenericCallback, this );
219     var_DelCallback( getIntf()->p_sys->p_playlist, "repeat",
220                      onGenericCallback, this );
221
222     var_DelCallback( getIntf()->p_sys->p_playlist, "intf-change",
223                      onIntfChange, this );
224     var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-item-append",
225                      onItemAppend, this );
226     var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-item-deleted",
227                      onItemDelete, this );
228     var_DelCallback( getIntf()->p_sys->p_playlist, "input-current",
229                      onInputNew, this );
230     var_DelCallback( getIntf()->p_sys->p_playlist, "item-change",
231                      onItemChange, this );
232     var_DelCallback( getIntf(), "skin-to-load", onSkinToLoad, this );
233     var_DelCallback( getIntf(), "interaction", onInteraction, this );
234 }
235
236 void VlcProc::manage()
237 {
238     // Did the user request to quit vlc ?
239     if( !vlc_object_alive( getIntf() ) )
240     {
241         // Get the instance of OSFactory
242         OSFactory *pOsFactory = OSFactory::instance( getIntf() );
243
244         // Exit the main OS loop
245         pOsFactory->getOSLoop()->exit();
246
247         return;
248     }
249 }
250
251 void VlcProc::CmdManage::execute()
252 {
253     // Just forward to VlcProc
254     m_pParent->manage();
255 }
256
257
258 int VlcProc::onIntfChange( vlc_object_t *pObj, const char *pVariable,
259                            vlc_value_t oldVal, vlc_value_t newVal,
260                            void *pParam )
261 {
262     VlcProc *pThis = (VlcProc*)pParam;
263
264     // Update the stream variable
265     pThis->updateStreamName();
266
267     // Create a playtree notify command (for new style playtree)
268     CmdPlaytreeChanged *pCmdTree = new CmdPlaytreeChanged( pThis->getIntf() );
269
270     // Push the command in the asynchronous command queue
271     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
272     pQueue->push( CmdGenericPtr( pCmdTree ) );
273
274     return VLC_SUCCESS;
275 }
276
277
278
279 int VlcProc::onInputNew( vlc_object_t *pObj, const char *pVariable,
280                          vlc_value_t oldval, vlc_value_t newval, void *pParam )
281 {
282     VlcProc *pThis = (VlcProc*)pParam;
283     input_thread_t *pInput = static_cast<input_thread_t*>(newval.p_address);
284
285     var_AddCallback( pInput, "intf-event", onGenericCallback, pThis );
286     var_AddCallback( pInput, "bit-rate", onGenericCallback, pThis );
287     var_AddCallback( pInput, "sample-rate", onGenericCallback, pThis );
288     var_AddCallback( pInput, "can-record", onGenericCallback, pThis );
289
290     return VLC_SUCCESS;
291 }
292
293
294 int VlcProc::onItemChange( vlc_object_t *pObj, const char *pVariable,
295                            vlc_value_t oldval, vlc_value_t newval,
296                            void *pParam )
297 {
298     VlcProc *pThis = (VlcProc*)pParam;
299     input_item_t *p_item = static_cast<input_item_t*>(newval.p_address);
300
301     // Update the stream variable
302     pThis->updateStreamName();
303
304     // Create a playtree notify command
305     CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
306                                                          p_item->i_id );
307
308     // Push the command in the asynchronous command queue
309     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
310     pQueue->push( CmdGenericPtr( pCmdTree ), true );
311
312     return VLC_SUCCESS;
313 }
314
315 int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable,
316                            vlc_value_t oldVal, vlc_value_t newVal,
317                            void *pParam )
318 {
319     VlcProc *pThis = (VlcProc*)pParam;
320
321     playlist_add_t *p_add = (playlist_add_t*)malloc( sizeof(
322                                                 playlist_add_t ) ) ;
323
324     memcpy( p_add, newVal.p_address, sizeof( playlist_add_t ) ) ;
325
326     CmdGenericPtr ptrTree;
327     CmdPlaytreeAppend *pCmdTree = new CmdPlaytreeAppend( pThis->getIntf(),
328                                                              p_add );
329     ptrTree = CmdGenericPtr( pCmdTree );
330
331     // Push the command in the asynchronous command queue
332     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
333     pQueue->push( ptrTree , false );
334
335     return VLC_SUCCESS;
336 }
337
338 int VlcProc::onItemDelete( vlc_object_t *pObj, const char *pVariable,
339                            vlc_value_t oldVal, vlc_value_t newVal,
340                            void *pParam )
341 {
342     VlcProc *pThis = (VlcProc*)pParam;
343
344     int i_id = newVal.i_int;
345
346     CmdGenericPtr ptrTree;
347     CmdPlaytreeDelete *pCmdTree = new CmdPlaytreeDelete( pThis->getIntf(),
348                                                          i_id);
349     ptrTree = CmdGenericPtr( pCmdTree );
350
351     // Push the command in the asynchronous command queue
352     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
353     pQueue->push( ptrTree , false );
354
355     return VLC_SUCCESS;
356 }
357
358
359 int VlcProc::onSkinToLoad( 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     // Create a playlist notify command
366     CmdChangeSkin *pCmd =
367         new CmdChangeSkin( pThis->getIntf(), newVal.psz_string );
368
369     // Push the command in the asynchronous command queue
370     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
371     pQueue->push( CmdGenericPtr( pCmd ) );
372
373     return VLC_SUCCESS;
374 }
375
376 int VlcProc::onInteraction( vlc_object_t *pObj, const char *pVariable,
377                             vlc_value_t oldVal, vlc_value_t newVal,
378                             void *pParam )
379 {
380     VlcProc *pThis = (VlcProc*)pParam;
381     interaction_dialog_t *p_dialog = (interaction_dialog_t *)(newVal.p_address);
382
383     CmdInteraction *pCmd = new CmdInteraction( pThis->getIntf(), p_dialog );
384     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
385     pQueue->push( CmdGenericPtr( pCmd ) );
386     return VLC_SUCCESS;
387 }
388
389
390 void VlcProc::updateStreamName()
391 {
392     // Create a update item command
393     CmdUpdateItem *pCmdItem = new CmdUpdateItem( getIntf(), getStreamNameVar(), getStreamURIVar() );
394
395     // Push the command in the asynchronous command queue
396     AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
397     pQueue->push( CmdGenericPtr( pCmdItem ) );
398 }
399
400 int VlcProc::onEqBandsChange( vlc_object_t *pObj, const char *pVariable,
401                               vlc_value_t oldVal, vlc_value_t newVal,
402                               void *pParam )
403 {
404     VlcProc *pThis = (VlcProc*)pParam;
405
406     // Post a set equalizer bands command
407     CmdSetEqBands *pCmd = new CmdSetEqBands( pThis->getIntf(),
408                                              pThis->m_varEqBands,
409                                              newVal.psz_string );
410     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
411     pQueue->push( CmdGenericPtr( pCmd ) );
412
413     return VLC_SUCCESS;
414 }
415
416
417 int VlcProc::onEqPreampChange( vlc_object_t *pObj, const char *pVariable,
418                                vlc_value_t oldVal, vlc_value_t newVal,
419                                void *pParam )
420 {
421     VlcProc *pThis = (VlcProc*)pParam;
422     EqualizerPreamp *pVarPreamp = (EqualizerPreamp*)(pThis->m_cVarEqPreamp.get());
423
424     // Post a set preamp command
425     CmdSetEqPreamp *pCmd = new CmdSetEqPreamp( pThis->getIntf(), *pVarPreamp,
426                                               (newVal.f_float + 20.0) / 40.0 );
427     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
428     pQueue->push( CmdGenericPtr( pCmd ) );
429
430     return VLC_SUCCESS;
431 }
432
433
434 int VlcProc::onGenericCallback( vlc_object_t *pObj, const char *pVariable,
435                                 vlc_value_t oldVal, vlc_value_t newVal,
436                                 void *pParam )
437 {
438     VlcProc *pThis = (VlcProc*)pParam;
439     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
440
441     CmdGeneric *pCmd = NULL;
442
443 #define ADD_CALLBACK_ENTRY( var, label ) \
444     { \
445     if( strcmp( pVariable, var ) == 0 ) \
446         pCmd = new Cmd_##label( pThis->getIntf(), pObj, newVal ); \
447     }
448
449     ADD_CALLBACK_ENTRY( "item-current", item_current_changed )
450     ADD_CALLBACK_ENTRY( "volume-change", volume_changed )
451
452     ADD_CALLBACK_ENTRY( "intf-event", intf_event_changed )
453     ADD_CALLBACK_ENTRY( "bit-rate", bit_rate_changed )
454     ADD_CALLBACK_ENTRY( "sample-rate", sample_rate_changed )
455     ADD_CALLBACK_ENTRY( "can-record", can_record_changed )
456
457     ADD_CALLBACK_ENTRY( "random", random_changed )
458     ADD_CALLBACK_ENTRY( "loop", loop_changed )
459     ADD_CALLBACK_ENTRY( "repeat", repeat_changed )
460
461     ADD_CALLBACK_ENTRY( "audio-filter", audio_filter_changed )
462
463     ADD_CALLBACK_ENTRY( "intf-show", intf_show_changed )
464
465 #undef ADD_CALLBACK_ENTRY
466
467     if( pCmd )
468         pQueue->push( CmdGenericPtr( pCmd ), false );
469     else
470         msg_Err( pObj, "no Callback entry provided for %s", pVariable );
471
472     return VLC_SUCCESS;
473 }
474
475 void VlcProc::on_item_current_changed( vlc_object_t* p_obj, vlc_value_t newVal )
476 {
477     input_item_t *p_item = static_cast<input_item_t*>(newVal.p_address);
478
479     // Update the stream variable
480     updateStreamName();
481
482     // Create a playtree notify command
483     AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
484     CmdPlaytreeUpdate *pCmdTree =
485             new CmdPlaytreeUpdate( getIntf(), p_item->i_id );
486     pQueue->push( CmdGenericPtr( pCmdTree ) , true );
487 }
488
489 #define SET_BOOL(m,v)         ((VarBoolImpl*)(m).get())->set(v)
490 #define SET_STREAMTIME(m,v,b) ((StreamTime*)(m).get())->set(v,b)
491 #define SET_TEXT(m,v)         ((VarText*)(m).get())->set(v)
492 #define SET_VOLUME(m,v,b)     ((Volume*)(m).get())->set(v,b)
493
494 void VlcProc::on_intf_event_changed( vlc_object_t* p_obj, vlc_value_t newVal )
495 {
496     input_thread_t* pInput = (input_thread_t*) p_obj;
497
498     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
499
500     if( !getIntf()->p_sys->p_input )
501     {
502         msg_Dbg( getIntf(), "new input %p detected", pInput );
503
504         getIntf()->p_sys->p_input = pInput;
505         vlc_object_hold( pInput );
506     }
507
508     switch( newVal.i_int )
509     {
510         case INPUT_EVENT_STATE:
511         {
512             int state = var_GetInteger( pInput, "state" );
513             SET_BOOL( m_cVarStopped, false );
514             SET_BOOL( m_cVarPlaying, state != PAUSE_S );
515             SET_BOOL( m_cVarPaused, state == PAUSE_S );
516             break;
517         }
518
519         case INPUT_EVENT_POSITION:
520         {
521             float pos = var_GetFloat( pInput, "position" );
522             SET_STREAMTIME( m_cVarTime, pos, false );
523             SET_BOOL( m_cVarSeekable, pos != 0.0 );
524             break;
525         }
526
527         case INPUT_EVENT_ES:
528         {
529             // Do we have audio
530             vlc_value_t audio_es;
531             var_Change( pInput, "audio-es", VLC_VAR_CHOICESCOUNT,
532                             &audio_es, NULL );
533             SET_BOOL( m_cVarHasAudio, audio_es.i_int > 0 );
534             break;
535         }
536
537         case INPUT_EVENT_VOUT:
538         {
539             vout_thread_t* pVout = input_GetVout( pInput );
540             SET_BOOL( m_cVarHasVout, pVout != NULL );
541             if( pVout )
542             {
543                 SET_BOOL( m_cVarFullscreen,
544                                          var_GetBool( pVout, "fullscreen" ) );
545                 vlc_object_release( pVout );
546             }
547             break;
548         }
549
550         case INPUT_EVENT_AOUT:
551         {
552             aout_instance_t* pAout = input_GetAout( pInput );
553
554             // end of input or aout reuse (nothing to do)
555             if( !pAout || pAout == m_pAout )
556             {
557                 if( pAout )
558                     vlc_object_release( pAout );
559                 break;
560             }
561
562             // remove previous Aout if any
563             if( m_pAout )
564             {
565                 var_DelCallback( m_pAout, "audio-filter",
566                                  onGenericCallback, this );
567                 if( m_bEqualizer_started )
568                 {
569                     var_DelCallback( m_pAout, "equalizer-bands",
570                                      onEqBandsChange, this );
571                     var_DelCallback( m_pAout, "equalizer-preamp",
572                                      onEqPreampChange, this );
573                 }
574                 vlc_object_release( m_pAout );
575                 m_pAout = NULL;
576                 m_bEqualizer_started = false;
577             }
578
579             // New Aout (addCallbacks)
580             var_AddCallback( pAout, "audio-filter", onGenericCallback, this );
581
582             char *pFilters = var_GetNonEmptyString( pAout, "audio-filter" );
583             bool b_equalizer = pFilters && strstr( pFilters, "equalizer" );
584             free( pFilters );
585             SET_BOOL( m_cVarEqualizer, b_equalizer );
586             if( b_equalizer )
587             {
588                 var_AddCallback( pAout, "equalizer-bands",
589                               onEqBandsChange, this );
590                 var_AddCallback( pAout, "equalizer-preamp",
591                               onEqPreampChange, this );
592                 m_bEqualizer_started = true;
593             }
594             m_pAout = pAout;
595             break;
596         }
597
598         case INPUT_EVENT_CHAPTER:
599         {
600             vlc_value_t chapters_count;
601             var_Change( pInput, "chapter", VLC_VAR_CHOICESCOUNT,
602                         &chapters_count, NULL );
603             SET_BOOL( m_cVarDvdActive, chapters_count.i_int > 0 );
604             break;
605         }
606
607         case INPUT_EVENT_RECORD:
608             SET_BOOL( m_cVarRecording, var_GetBool( pInput, "record" ) );
609             break;
610
611         case INPUT_EVENT_DEAD:
612             msg_Dbg( getIntf(), "end of input detected for %p", pInput );
613
614             var_DelCallback( pInput, "intf-event", onGenericCallback, this );
615             var_DelCallback( pInput, "bit-rate", onGenericCallback, this );
616             var_DelCallback( pInput, "sample-rate", onGenericCallback, this );
617             var_DelCallback( pInput, "can-record" , onGenericCallback, this );
618             vlc_object_release( pInput );
619             getIntf()->p_sys->p_input = NULL;
620             reset_input();
621             break;
622
623         default:
624             break;
625     }
626 }
627
628 void VlcProc::on_bit_rate_changed( vlc_object_t* p_obj, vlc_value_t newVal )
629 {
630     input_thread_t* pInput = (input_thread_t*) p_obj;
631
632     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
633
634     int bitrate = var_GetInteger( pInput, "bit-rate" ) / 1000;
635     SET_TEXT( m_cVarStreamBitRate, UString::fromInt( getIntf(), bitrate ) );
636 }
637
638 void VlcProc::on_sample_rate_changed( vlc_object_t* p_obj, vlc_value_t newVal )
639 {
640     input_thread_t* pInput = (input_thread_t*) p_obj;
641
642     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
643
644     int sampleRate = var_GetInteger( pInput, "sample-rate" ) / 1000;
645     SET_TEXT( m_cVarStreamSampleRate, UString::fromInt(getIntf(),sampleRate) );
646 }
647
648 void VlcProc::on_can_record_changed( vlc_object_t* p_obj, vlc_value_t newVal )
649 {
650     input_thread_t* pInput = (input_thread_t*) p_obj;
651
652     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
653
654     SET_BOOL( m_cVarRecordable, var_GetBool(  pInput, "can-record" ) );
655 }
656
657 void VlcProc::on_random_changed( vlc_object_t* p_obj, vlc_value_t newVal )
658 {
659     playlist_t* pPlaylist = (playlist_t*) p_obj;
660
661     SET_BOOL( m_cVarRandom, var_GetBool( pPlaylist, "random" ) );
662 }
663
664 void VlcProc::on_loop_changed( vlc_object_t* p_obj, vlc_value_t newVal )
665 {
666     playlist_t* pPlaylist = (playlist_t*) p_obj;
667
668     SET_BOOL( m_cVarLoop, var_GetBool( pPlaylist, "loop" ) );
669 }
670
671 void VlcProc::on_repeat_changed( vlc_object_t* p_obj, vlc_value_t newVal )
672 {
673     playlist_t* pPlaylist = (playlist_t*) p_obj;
674
675     SET_BOOL( m_cVarRepeat, var_GetBool( pPlaylist, "repeat" ) );
676 }
677
678 void VlcProc::on_volume_changed( vlc_object_t* p_obj, vlc_value_t newVal )
679 {
680     (void)p_obj; (void)newVal;
681     playlist_t* pPlaylist = getIntf()->p_sys->p_playlist;
682
683     audio_volume_t volume;
684     aout_VolumeGet( pPlaylist, &volume );
685     SET_VOLUME( m_cVarVolume, (double)volume / AOUT_VOLUME_MAX, false );
686     SET_BOOL( m_cVarMute, volume == 0 );
687 }
688
689 void VlcProc::on_audio_filter_changed( vlc_object_t* p_obj, vlc_value_t newVal )
690 {
691     aout_instance_t* pAout = (aout_instance_t*) p_obj;
692
693     char *pFilters = newVal.psz_string;
694
695     bool b_equalizer = pFilters && strstr( pFilters, "equalizer" );
696     SET_BOOL( m_cVarEqualizer, b_equalizer );
697     if( b_equalizer && !m_bEqualizer_started )
698     {
699         var_AddCallback( pAout, "equalizer-bands", onEqBandsChange, this );
700         var_AddCallback( pAout, "equalizer-preamp", onEqPreampChange, this );
701         m_bEqualizer_started = true;
702     }
703 }
704
705 void VlcProc::on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal )
706 {
707     (void)p_obj;
708     bool b_fullscreen = getFullscreenVar().get();
709
710     if( !b_fullscreen )
711     {
712         if( newVal.b_bool )
713         {
714             // Create a raise all command
715             CmdRaiseAll *pCmd = new CmdRaiseAll( getIntf(),
716                 getIntf()->p_sys->p_theme->getWindowManager() );
717
718             // Push the command in the asynchronous command queue
719             AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
720             pQueue->push( CmdGenericPtr( pCmd ) );
721         }
722     }
723     else
724     {
725         Theme* pTheme =  getIntf()->p_sys->p_theme;
726         TopWindow *pWin = pTheme->getWindowById( "fullscreenController" );
727         if( pWin )
728         {
729             bool b_visible = pWin->getVisibleVar().get();
730             AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
731
732             if( !b_visible )
733             {
734                CmdShowWindow* pCmd = new CmdShowWindow( getIntf(),
735                              getIntf()->p_sys->p_theme->getWindowManager(),
736                              *pWin );
737                pQueue->push( CmdGenericPtr( pCmd ) );
738             }
739             else
740             {
741                CmdHideWindow* pCmd = new CmdHideWindow( getIntf(),
742                               getIntf()->p_sys->p_theme->getWindowManager(),
743                               *pWin );
744                pQueue->push( CmdGenericPtr( pCmd ) );
745             }
746         }
747     }
748 }
749
750 void VlcProc::reset_input()
751 {
752     SET_BOOL( m_cVarSeekable, false );
753     SET_BOOL( m_cVarRecordable, false );
754     SET_BOOL( m_cVarRecording, false );
755     SET_BOOL( m_cVarDvdActive, false );
756     SET_BOOL( m_cVarFullscreen, false );
757     SET_BOOL( m_cVarHasAudio, false );
758     SET_BOOL( m_cVarHasVout, false );
759     SET_BOOL( m_cVarStopped, true );
760     SET_BOOL( m_cVarPlaying, false );
761     SET_BOOL( m_cVarPaused, false );
762
763     SET_STREAMTIME( m_cVarTime, 0, false );
764     SET_TEXT( m_cVarStreamBitRate, UString( getIntf(), "") );
765     SET_TEXT( m_cVarStreamSampleRate, UString( getIntf(), "") );
766 }
767
768 void VlcProc::init_variables()
769 {
770     playlist_t* pPlaylist = getIntf()->p_sys->p_playlist;
771
772     SET_BOOL( m_cVarRandom, var_GetBool( pPlaylist, "random" ) );
773     SET_BOOL( m_cVarLoop, var_GetBool( pPlaylist, "loop" ) );
774     SET_BOOL( m_cVarRepeat, var_GetBool( pPlaylist, "repeat" ) );
775
776     audio_volume_t volume;
777     aout_VolumeGet( pPlaylist, &volume );
778     SET_VOLUME( m_cVarVolume, (double)volume / AOUT_VOLUME_MAX, false );
779     SET_BOOL( m_cVarMute, volume == 0 );
780
781     update_equalizer();
782 }
783
784 void VlcProc::update_equalizer()
785 {
786
787     char *pFilters;
788     if( m_pAout )
789         pFilters = var_GetNonEmptyString( m_pAout, "audio-filter" );
790     else
791         pFilters = config_GetPsz( getIntf(), "audio-filter" );
792
793     bool b_equalizer = pFilters && strstr( pFilters, "equalizer" );
794     free( pFilters );
795
796     SET_BOOL( m_cVarEqualizer, b_equalizer );
797 }
798
799 void VlcProc::setFullscreenVar( bool b_fullscreen )
800 {
801     SET_BOOL( m_cVarFullscreen, b_fullscreen );
802 }
803
804 #undef  SET_BOOL
805 #undef  SET_STREAMTIME
806 #undef  SET_TEXT
807 #undef  SET_VOLUME