]> git.sesse.net Git - vlc/blob - modules/gui/skins2/src/vlcproc.cpp
skins2: translate $F into local path instead of uri when possible
[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 #include <vlc_url.h>
35
36 #include "vlcproc.hpp"
37 #include "os_factory.hpp"
38 #include "os_loop.hpp"
39 #include "os_timer.hpp"
40 #include "var_manager.hpp"
41 #include "vout_manager.hpp"
42 #include "theme.hpp"
43 #include "window_manager.hpp"
44 #include "../commands/async_queue.hpp"
45 #include "../commands/cmd_change_skin.hpp"
46 #include "../commands/cmd_show_window.hpp"
47 #include "../commands/cmd_quit.hpp"
48 #include "../commands/cmd_resize.hpp"
49 #include "../commands/cmd_vars.hpp"
50 #include "../commands/cmd_dialogs.hpp"
51 #include "../commands/cmd_audio.hpp"
52 #include "../commands/cmd_callbacks.hpp"
53 #include "../utils/var_bool.hpp"
54 #include "../utils/var_string.hpp"
55 #include <sstream>
56
57 #include <assert.h>
58
59 VlcProc *VlcProc::instance( intf_thread_t *pIntf )
60 {
61     if( pIntf->p_sys->p_vlcProc == NULL )
62     {
63         pIntf->p_sys->p_vlcProc = new VlcProc( pIntf );
64     }
65
66     return pIntf->p_sys->p_vlcProc;
67 }
68
69
70 void VlcProc::destroy( intf_thread_t *pIntf )
71 {
72     delete pIntf->p_sys->p_vlcProc;
73     pIntf->p_sys->p_vlcProc = NULL;
74 }
75
76
77 VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ),
78     m_varEqBands( pIntf ), m_pVout( NULL ), m_pAout( NULL ),
79     m_bEqualizer_started( false ), 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     m_cVarStreamArt = VariablePtr( new VarString( getIntf() ) );
135     pVarManager->registerVar( m_cVarStreamArt, "streamArt" );
136
137     // Register the equalizer bands
138     for( int i = 0; i < EqualizerBands::kNbBands; i++)
139     {
140         stringstream ss;
141         ss << "equalizer.band(" << i << ")";
142         pVarManager->registerVar( m_varEqBands.getBand( i ), ss.str() );
143     }
144
145     // XXX WARNING XXX
146     // The object variable callbacks are called from other VLC threads,
147     // so they must put commands in the queue and NOT do anything else
148     // (X11 calls are not reentrant)
149
150 #define ADD_CALLBACK( p_object, var ) \
151     var_AddCallback( p_object, var, onGenericCallback, this );
152
153     ADD_CALLBACK( pIntf->p_sys->p_playlist, "volume-change" )
154     ADD_CALLBACK( pIntf->p_libvlc, "intf-show" )
155
156     ADD_CALLBACK( pIntf->p_sys->p_playlist, "item-current" )
157     ADD_CALLBACK( pIntf->p_sys->p_playlist, "random" )
158     ADD_CALLBACK( pIntf->p_sys->p_playlist, "loop" )
159     ADD_CALLBACK( pIntf->p_sys->p_playlist, "repeat" )
160
161 #undef ADD_CALLBACK
162
163     // Called when a playlist item is added
164     var_AddCallback( pIntf->p_sys->p_playlist, "playlist-item-append",
165                      onItemAppend, this );
166     // Called when a playlist item is deleted
167     // TODO: properly handle item-deleted
168     var_AddCallback( pIntf->p_sys->p_playlist, "playlist-item-deleted",
169                      onItemDelete, this );
170     // Called when the current input changes
171     var_AddCallback( pIntf->p_sys->p_playlist, "input-current",
172                      onInputNew, this );
173     // Called when a playlist item changed
174     var_AddCallback( pIntf->p_sys->p_playlist, "item-change",
175                      onItemChange, this );
176
177     // Called when we have an interaction dialog to display
178     var_Create( pIntf, "interaction", VLC_VAR_ADDRESS );
179     var_AddCallback( pIntf, "interaction", onInteraction, this );
180     interaction_Register( pIntf );
181
182     // initialize variables refering to liblvc and playlist objects
183     init_variables();
184 }
185
186
187 VlcProc::~VlcProc()
188 {
189     m_pTimer->stop();
190     delete( m_pTimer );
191
192     if( m_pAout )
193     {
194         vlc_object_release( m_pAout );
195         m_pAout = NULL;
196     }
197     if( m_pVout )
198     {
199         vlc_object_release( m_pVout );
200         m_pVout = NULL;
201     }
202
203     interaction_Unregister( getIntf() );
204
205     var_DelCallback( getIntf()->p_sys->p_playlist, "volume-change",
206                      onGenericCallback, this );
207     var_DelCallback( getIntf()->p_libvlc, "intf-show",
208                      onGenericCallback, this );
209
210     var_DelCallback( getIntf()->p_sys->p_playlist, "item-current",
211                      onGenericCallback, this );
212     var_DelCallback( getIntf()->p_sys->p_playlist, "random",
213                      onGenericCallback, this );
214     var_DelCallback( getIntf()->p_sys->p_playlist, "loop",
215                      onGenericCallback, this );
216     var_DelCallback( getIntf()->p_sys->p_playlist, "repeat",
217                      onGenericCallback, this );
218
219     var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-item-append",
220                      onItemAppend, this );
221     var_DelCallback( getIntf()->p_sys->p_playlist, "playlist-item-deleted",
222                      onItemDelete, this );
223     var_DelCallback( getIntf()->p_sys->p_playlist, "input-current",
224                      onInputNew, this );
225     var_DelCallback( getIntf()->p_sys->p_playlist, "item-change",
226                      onItemChange, this );
227     var_DelCallback( getIntf(), "interaction", onInteraction, this );
228 }
229
230 void VlcProc::manage()
231 {
232     // Did the user request to quit vlc ?
233     if( !vlc_object_alive( getIntf() ) )
234     {
235         // Get the instance of OSFactory
236         OSFactory *pOsFactory = OSFactory::instance( getIntf() );
237
238         // Exit the main OS loop
239         pOsFactory->getOSLoop()->exit();
240
241         return;
242     }
243 }
244
245 void VlcProc::CmdManage::execute()
246 {
247     // Just forward to VlcProc
248     m_pParent->manage();
249 }
250
251
252 int VlcProc::onInputNew( vlc_object_t *pObj, const char *pVariable,
253                          vlc_value_t oldval, vlc_value_t newval, void *pParam )
254 {
255     VlcProc *pThis = (VlcProc*)pParam;
256     input_thread_t *pInput = static_cast<input_thread_t*>(newval.p_address);
257
258     var_AddCallback( pInput, "intf-event", onGenericCallback2, pThis );
259     var_AddCallback( pInput, "bit-rate", onGenericCallback, pThis );
260     var_AddCallback( pInput, "sample-rate", onGenericCallback, pThis );
261     var_AddCallback( pInput, "can-record", onGenericCallback, pThis );
262
263     return VLC_SUCCESS;
264 }
265
266
267 int VlcProc::onItemChange( vlc_object_t *pObj, const char *pVariable,
268                            vlc_value_t oldval, vlc_value_t newval,
269                            void *pParam )
270 {
271     VlcProc *pThis = (VlcProc*)pParam;
272     input_item_t *p_item = static_cast<input_item_t*>(newval.p_address);
273
274     // Create a playtree notify command
275     CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
276                                                          p_item );
277
278     // Push the command in the asynchronous command queue
279     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
280     pQueue->push( CmdGenericPtr( pCmdTree ), true );
281
282     return VLC_SUCCESS;
283 }
284
285 int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable,
286                            vlc_value_t oldVal, vlc_value_t newVal,
287                            void *pParam )
288 {
289     VlcProc *pThis = (VlcProc*)pParam;
290
291     playlist_add_t *p_add = static_cast<playlist_add_t*>(newVal.p_address);
292
293     CmdGenericPtr ptrTree;
294     CmdPlaytreeAppend *pCmdTree = new CmdPlaytreeAppend( pThis->getIntf(),
295                                                              p_add );
296     ptrTree = CmdGenericPtr( pCmdTree );
297
298     // Push the command in the asynchronous command queue
299     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
300     pQueue->push( ptrTree , false );
301
302     return VLC_SUCCESS;
303 }
304
305 int VlcProc::onItemDelete( vlc_object_t *pObj, const char *pVariable,
306                            vlc_value_t oldVal, vlc_value_t newVal,
307                            void *pParam )
308 {
309     VlcProc *pThis = (VlcProc*)pParam;
310
311     int i_id = newVal.i_int;
312
313     CmdGenericPtr ptrTree;
314     CmdPlaytreeDelete *pCmdTree = new CmdPlaytreeDelete( pThis->getIntf(),
315                                                          i_id);
316     ptrTree = CmdGenericPtr( pCmdTree );
317
318     // Push the command in the asynchronous command queue
319     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
320     pQueue->push( ptrTree , false );
321
322     return VLC_SUCCESS;
323 }
324
325 int VlcProc::onInteraction( vlc_object_t *pObj, const char *pVariable,
326                             vlc_value_t oldVal, vlc_value_t newVal,
327                             void *pParam )
328 {
329     VlcProc *pThis = (VlcProc*)pParam;
330     interaction_dialog_t *p_dialog = (interaction_dialog_t *)(newVal.p_address);
331
332     CmdInteraction *pCmd = new CmdInteraction( pThis->getIntf(), p_dialog );
333     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
334     pQueue->push( CmdGenericPtr( pCmd ) );
335     return VLC_SUCCESS;
336 }
337
338 int VlcProc::onEqBandsChange( 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     // Post a set equalizer bands command
345     CmdSetEqBands *pCmd = new CmdSetEqBands( pThis->getIntf(),
346                                              pThis->m_varEqBands,
347                                              newVal.psz_string );
348     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
349     pQueue->push( CmdGenericPtr( pCmd ) );
350
351     return VLC_SUCCESS;
352 }
353
354
355 int VlcProc::onEqPreampChange( vlc_object_t *pObj, const char *pVariable,
356                                vlc_value_t oldVal, vlc_value_t newVal,
357                                void *pParam )
358 {
359     VlcProc *pThis = (VlcProc*)pParam;
360     EqualizerPreamp *pVarPreamp = (EqualizerPreamp*)(pThis->m_cVarEqPreamp.get());
361
362     // Post a set preamp command
363     CmdSetEqPreamp *pCmd = new CmdSetEqPreamp( pThis->getIntf(), *pVarPreamp,
364                                               (newVal.f_float + 20.0) / 40.0 );
365     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
366     pQueue->push( CmdGenericPtr( pCmd ) );
367
368     return VLC_SUCCESS;
369 }
370
371
372 int VlcProc::onGenericCallback( vlc_object_t *pObj, const char *pVariable,
373                                 vlc_value_t oldVal, vlc_value_t newVal,
374                                 void *pParam )
375 {
376     VlcProc *pThis = (VlcProc*)pParam;
377     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
378
379 #define ADD_CALLBACK_ENTRY( var, func, remove ) \
380     { \
381     if( strcmp( pVariable, var ) == 0 ) \
382     { \
383         string label = var; \
384         CmdGeneric *pCmd = new CmdCallback( pThis->getIntf(), pObj, newVal, \
385                                             &VlcProc::func, label ); \
386         if( pCmd ) \
387             pQueue->push( CmdGenericPtr( pCmd ), remove ); \
388         return VLC_SUCCESS; \
389     } \
390     }
391
392     ADD_CALLBACK_ENTRY( "item-current", on_item_current_changed, false )
393     ADD_CALLBACK_ENTRY( "volume-change", on_volume_changed, true )
394
395     ADD_CALLBACK_ENTRY( "bit-rate", on_bit_rate_changed, false )
396     ADD_CALLBACK_ENTRY( "sample-rate", on_sample_rate_changed, false )
397     ADD_CALLBACK_ENTRY( "can-record", on_can_record_changed, false )
398
399     ADD_CALLBACK_ENTRY( "random", on_random_changed, false )
400     ADD_CALLBACK_ENTRY( "loop", on_loop_changed, false )
401     ADD_CALLBACK_ENTRY( "repeat", on_repeat_changed, false )
402
403     ADD_CALLBACK_ENTRY( "audio-filter", on_audio_filter_changed, false )
404
405     ADD_CALLBACK_ENTRY( "intf-show", on_intf_show_changed, false )
406
407 #undef ADD_CALLBACK_ENTRY
408
409     msg_Err( pThis->getIntf(), "no callback entry for %s", pVariable );
410     return VLC_EGENERIC;
411 }
412
413
414 int VlcProc::onGenericCallback2( vlc_object_t *pObj, const char *pVariable,
415                                  vlc_value_t oldVal, vlc_value_t newVal,
416                                  void *pParam )
417 {
418     VlcProc *pThis = (VlcProc*)pParam;
419     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
420
421     /**
422      * For intf-event, commands are labeled based on the value of newVal.
423      *
424      * For some values (e.g position), only keep the latest command
425      * when there are multiple pending commands (remove=true).
426      *
427      * for others, don't discard commands (remove=false)
428      **/
429     if( strcmp( pVariable, "intf-event" ) == 0 )
430     {
431         stringstream label;
432         bool b_remove;
433         switch( newVal.i_int )
434         {
435             case INPUT_EVENT_STATE:
436             case INPUT_EVENT_POSITION:
437             case INPUT_EVENT_ES:
438             case INPUT_EVENT_CHAPTER:
439             case INPUT_EVENT_RECORD:
440                 b_remove = true;
441                 break;
442             case INPUT_EVENT_VOUT:
443             case INPUT_EVENT_AOUT:
444             case INPUT_EVENT_DEAD:
445                 b_remove = false;
446                 break;
447             default:
448                 return VLC_SUCCESS;
449         }
450         label <<  pVariable << "_" << newVal.i_int;
451         CmdGeneric *pCmd = new CmdCallback( pThis->getIntf(), pObj, newVal,
452                                             &VlcProc::on_intf_event_changed,
453                                             label.str() );
454         if( pCmd )
455             pQueue->push( CmdGenericPtr( pCmd ), b_remove );
456
457         return VLC_SUCCESS;
458     }
459
460     msg_Err( pThis->getIntf(), "no callback entry for %s", pVariable );
461     return VLC_EGENERIC;
462 }
463
464
465 #define SET_BOOL(m,v)         ((VarBoolImpl*)(m).get())->set(v)
466 #define SET_STREAMTIME(m,v,b) ((StreamTime*)(m).get())->set(v,b)
467 #define SET_TEXT(m,v)         ((VarText*)(m).get())->set(v)
468 #define SET_STRING(m,v)       ((VarString*)(m).get())->set(v)
469 #define SET_VOLUME(m,v,b)     ((Volume*)(m).get())->set(v,b)
470
471 void VlcProc::on_item_current_changed( vlc_object_t* p_obj, vlc_value_t newVal )
472 {
473     input_item_t *p_item = static_cast<input_item_t*>(newVal.p_address);
474
475     // Update short name
476     char *psz_name = input_item_GetName( p_item );
477     SET_TEXT( m_cVarStreamName, UString( getIntf(), psz_name ) );
478     free( psz_name );
479
480     // Update local path (if possible) or full uri
481     char *psz_uri = input_item_GetURI( p_item );
482     char *psz_path = make_path( psz_uri );
483     char *psz_save = psz_path ? psz_path : psz_uri;
484     SET_TEXT( m_cVarStreamURI, UString( getIntf(), psz_save ) );
485     free( psz_path );
486     free( psz_uri );
487
488     // Update art uri
489     char *psz_art = input_item_GetArtURL( p_item );
490     SET_STRING( m_cVarStreamArt, string( psz_art ? psz_art : "" ) );
491     free( psz_art );
492
493     // Update playtree
494     getPlaytreeVar().onUpdateCurrent( true );
495 }
496
497 void VlcProc::on_intf_event_changed( vlc_object_t* p_obj, vlc_value_t newVal )
498 {
499     input_thread_t* pInput = (input_thread_t*) p_obj;
500
501     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
502
503     if( !getIntf()->p_sys->p_input )
504     {
505         msg_Dbg( getIntf(), "new input %p detected", pInput );
506
507         getIntf()->p_sys->p_input = pInput;
508         vlc_object_hold( pInput );
509     }
510
511     switch( newVal.i_int )
512     {
513         case INPUT_EVENT_STATE:
514         {
515             int state = var_GetInteger( pInput, "state" );
516             SET_BOOL( m_cVarStopped, false );
517             SET_BOOL( m_cVarPlaying, state != PAUSE_S );
518             SET_BOOL( m_cVarPaused, state == PAUSE_S );
519             break;
520         }
521
522         case INPUT_EVENT_POSITION:
523         {
524             float pos = var_GetFloat( pInput, "position" );
525             SET_STREAMTIME( m_cVarTime, pos, false );
526             SET_BOOL( m_cVarSeekable, pos != 0.0 );
527             break;
528         }
529
530         case INPUT_EVENT_ES:
531         {
532             // Do we have audio
533             vlc_value_t audio_es;
534             var_Change( pInput, "audio-es", VLC_VAR_CHOICESCOUNT,
535                             &audio_es, NULL );
536             SET_BOOL( m_cVarHasAudio, audio_es.i_int > 0 );
537             break;
538         }
539
540         case INPUT_EVENT_VOUT:
541         {
542             vout_thread_t* pVout = input_GetVout( pInput );
543             SET_BOOL( m_cVarHasVout, pVout != NULL );
544             if( pVout )
545                 vlc_object_release( pVout );
546             break;
547         }
548
549         case INPUT_EVENT_AOUT:
550         {
551             aout_instance_t* pAout = input_GetAout( pInput );
552
553             // end of input or aout reuse (nothing to do)
554             if( !pAout || pAout == m_pAout )
555             {
556                 if( pAout )
557                     vlc_object_release( pAout );
558                 break;
559             }
560
561             // remove previous Aout if any
562             if( m_pAout )
563             {
564                 var_DelCallback( m_pAout, "audio-filter",
565                                  onGenericCallback, this );
566                 if( m_bEqualizer_started )
567                 {
568                     var_DelCallback( m_pAout, "equalizer-bands",
569                                      onEqBandsChange, this );
570                     var_DelCallback( m_pAout, "equalizer-preamp",
571                                      onEqPreampChange, this );
572                 }
573                 vlc_object_release( m_pAout );
574                 m_pAout = NULL;
575                 m_bEqualizer_started = false;
576             }
577
578             // New Aout (addCallbacks)
579             var_AddCallback( pAout, "audio-filter", onGenericCallback, this );
580
581             char *pFilters = var_GetNonEmptyString( pAout, "audio-filter" );
582             bool b_equalizer = pFilters && strstr( pFilters, "equalizer" );
583             free( pFilters );
584             SET_BOOL( m_cVarEqualizer, b_equalizer );
585             if( b_equalizer )
586             {
587                 var_AddCallback( pAout, "equalizer-bands",
588                               onEqBandsChange, this );
589                 var_AddCallback( pAout, "equalizer-preamp",
590                               onEqPreampChange, this );
591                 m_bEqualizer_started = true;
592             }
593             m_pAout = pAout;
594             break;
595         }
596
597         case INPUT_EVENT_CHAPTER:
598         {
599             vlc_value_t chapters_count;
600             var_Change( pInput, "chapter", VLC_VAR_CHOICESCOUNT,
601                         &chapters_count, NULL );
602             SET_BOOL( m_cVarDvdActive, chapters_count.i_int > 0 );
603             break;
604         }
605
606         case INPUT_EVENT_RECORD:
607             SET_BOOL( m_cVarRecording, var_GetBool( pInput, "record" ) );
608             break;
609
610         case INPUT_EVENT_DEAD:
611             msg_Dbg( getIntf(), "end of input detected for %p", pInput );
612
613             var_DelCallback( pInput, "intf-event", onGenericCallback2, this );
614             var_DelCallback( pInput, "bit-rate", onGenericCallback, this );
615             var_DelCallback( pInput, "sample-rate", onGenericCallback, this );
616             var_DelCallback( pInput, "can-record" , onGenericCallback, this );
617             vlc_object_release( pInput );
618             getIntf()->p_sys->p_input = NULL;
619             reset_input();
620             break;
621
622         default:
623             break;
624     }
625 }
626
627 void VlcProc::on_bit_rate_changed( vlc_object_t* p_obj, vlc_value_t newVal )
628 {
629     input_thread_t* pInput = (input_thread_t*) p_obj;
630
631     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
632
633     int bitrate = var_GetInteger( pInput, "bit-rate" ) / 1000;
634     SET_TEXT( m_cVarStreamBitRate, UString::fromInt( getIntf(), bitrate ) );
635 }
636
637 void VlcProc::on_sample_rate_changed( vlc_object_t* p_obj, vlc_value_t newVal )
638 {
639     input_thread_t* pInput = (input_thread_t*) p_obj;
640
641     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
642
643     int sampleRate = var_GetInteger( pInput, "sample-rate" ) / 1000;
644     SET_TEXT( m_cVarStreamSampleRate, UString::fromInt(getIntf(),sampleRate) );
645 }
646
647 void VlcProc::on_can_record_changed( vlc_object_t* p_obj, vlc_value_t newVal )
648 {
649     input_thread_t* pInput = (input_thread_t*) p_obj;
650
651     assert( getIntf()->p_sys->p_input == NULL || getIntf()->p_sys->p_input == pInput );
652
653     SET_BOOL( m_cVarRecordable, var_GetBool(  pInput, "can-record" ) );
654 }
655
656 void VlcProc::on_random_changed( vlc_object_t* p_obj, vlc_value_t newVal )
657 {
658     playlist_t* pPlaylist = (playlist_t*) p_obj;
659
660     SET_BOOL( m_cVarRandom, var_GetBool( pPlaylist, "random" ) );
661 }
662
663 void VlcProc::on_loop_changed( vlc_object_t* p_obj, vlc_value_t newVal )
664 {
665     playlist_t* pPlaylist = (playlist_t*) p_obj;
666
667     SET_BOOL( m_cVarLoop, var_GetBool( pPlaylist, "loop" ) );
668 }
669
670 void VlcProc::on_repeat_changed( vlc_object_t* p_obj, vlc_value_t newVal )
671 {
672     playlist_t* pPlaylist = (playlist_t*) p_obj;
673
674     SET_BOOL( m_cVarRepeat, var_GetBool( pPlaylist, "repeat" ) );
675 }
676
677 void VlcProc::on_volume_changed( vlc_object_t* p_obj, vlc_value_t newVal )
678 {
679     (void)p_obj; (void)newVal;
680     playlist_t* pPlaylist = getIntf()->p_sys->p_playlist;
681
682     audio_volume_t volume;
683     aout_VolumeGet( pPlaylist, &volume );
684     SET_VOLUME( m_cVarVolume, (double)volume / AOUT_VOLUME_MAX, false );
685     SET_BOOL( m_cVarMute, volume == 0 );
686 }
687
688 void VlcProc::on_audio_filter_changed( vlc_object_t* p_obj, vlc_value_t newVal )
689 {
690     aout_instance_t* pAout = (aout_instance_t*) p_obj;
691
692     char *pFilters = newVal.psz_string;
693
694     bool b_equalizer = pFilters && strstr( pFilters, "equalizer" );
695     SET_BOOL( m_cVarEqualizer, b_equalizer );
696     if( b_equalizer && !m_bEqualizer_started )
697     {
698         var_AddCallback( pAout, "equalizer-bands", onEqBandsChange, this );
699         var_AddCallback( pAout, "equalizer-preamp", onEqPreampChange, this );
700         m_bEqualizer_started = true;
701     }
702 }
703
704 void VlcProc::on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal )
705 {
706     (void)p_obj;
707     bool b_fullscreen = getFullscreenVar().get();
708
709     if( !b_fullscreen )
710     {
711         if( newVal.b_bool )
712         {
713             // Create a raise all command
714             CmdRaiseAll *pCmd = new CmdRaiseAll( getIntf(),
715                 getIntf()->p_sys->p_theme->getWindowManager() );
716
717             // Push the command in the asynchronous command queue
718             AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
719             pQueue->push( CmdGenericPtr( pCmd ) );
720         }
721     }
722     else
723     {
724         Theme* pTheme =  getIntf()->p_sys->p_theme;
725         TopWindow *pWin = pTheme->getWindowById( "fullscreenController" );
726         if( pWin )
727         {
728             bool b_visible = pWin->getVisibleVar().get();
729             AsyncQueue *pQueue = AsyncQueue::instance( getIntf() );
730
731             if( !b_visible )
732             {
733                CmdShowWindow* pCmd = new CmdShowWindow( getIntf(),
734                              getIntf()->p_sys->p_theme->getWindowManager(),
735                              *pWin );
736                pQueue->push( CmdGenericPtr( pCmd ) );
737             }
738             else
739             {
740                CmdHideWindow* pCmd = new CmdHideWindow( getIntf(),
741                               getIntf()->p_sys->p_theme->getWindowManager(),
742                               *pWin );
743                pQueue->push( CmdGenericPtr( pCmd ) );
744             }
745         }
746     }
747 }
748
749 void VlcProc::reset_input()
750 {
751     SET_BOOL( m_cVarSeekable, false );
752     SET_BOOL( m_cVarRecordable, false );
753     SET_BOOL( m_cVarRecording, false );
754     SET_BOOL( m_cVarDvdActive, false );
755     SET_BOOL( m_cVarHasAudio, false );
756     SET_BOOL( m_cVarHasVout, false );
757     SET_BOOL( m_cVarStopped, true );
758     SET_BOOL( m_cVarPlaying, false );
759     SET_BOOL( m_cVarPaused, false );
760
761     SET_STREAMTIME( m_cVarTime, 0, false );
762     SET_TEXT( m_cVarStreamName, UString( getIntf(), "") );
763     SET_TEXT( m_cVarStreamURI, UString( getIntf(), "") );
764     SET_TEXT( m_cVarStreamBitRate, UString( getIntf(), "") );
765     SET_TEXT( m_cVarStreamSampleRate, UString( getIntf(), "") );
766
767     getPlaytreeVar().onUpdateCurrent( false );
768 }
769
770 void VlcProc::init_variables()
771 {
772     playlist_t* pPlaylist = getIntf()->p_sys->p_playlist;
773
774     SET_BOOL( m_cVarRandom, var_GetBool( pPlaylist, "random" ) );
775     SET_BOOL( m_cVarLoop, var_GetBool( pPlaylist, "loop" ) );
776     SET_BOOL( m_cVarRepeat, var_GetBool( pPlaylist, "repeat" ) );
777
778     audio_volume_t volume;
779     aout_VolumeGet( pPlaylist, &volume );
780     SET_VOLUME( m_cVarVolume, (double)volume / AOUT_VOLUME_MAX, false );
781     SET_BOOL( m_cVarMute, volume == 0 );
782
783     update_equalizer();
784 }
785
786 void VlcProc::update_equalizer()
787 {
788
789     char *pFilters;
790     if( m_pAout )
791         pFilters = var_GetNonEmptyString( m_pAout, "audio-filter" );
792     else
793         pFilters = var_InheritString( getIntf(), "audio-filter" );
794
795     bool b_equalizer = pFilters && strstr( pFilters, "equalizer" );
796     free( pFilters );
797
798     SET_BOOL( m_cVarEqualizer, b_equalizer );
799 }
800
801 void VlcProc::setFullscreenVar( bool b_fullscreen )
802 {
803     SET_BOOL( m_cVarFullscreen, b_fullscreen );
804 }
805
806 #undef  SET_BOOL
807 #undef  SET_STREAMTIME
808 #undef  SET_TEXT
809 #undef  SET_STRING
810 #undef  SET_VOLUME