]> git.sesse.net Git - vlc/blob - modules/gui/qt4/main_interface.cpp
1eafbd71a115b5ba838f43356983bd041e1f6afd
[vlc] / modules / gui / qt4 / main_interface.cpp
1 /*****************************************************************************
2  * main_interface.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2011 VideoLAN and AUTHORS
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Jean-Baptiste Kempf <jb@videolan.org>
9  *          Ilkka Ollakka <ileoo@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
22  * along 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 "qt4.hpp"
31
32 #include "main_interface.hpp"
33 #include "input_manager.hpp"                    // Creation
34 #include "actions_manager.hpp"                  // killInstance
35 #include "extensions_manager.hpp"               // killInstance
36
37 #include "util/customwidgets.hpp"               // qtEventToVLCKey, QVLCStackedWidget
38 #include "util/qt_dirs.hpp"                     // toNativeSeparators
39
40 #include "components/interface_widgets.hpp"     // bgWidget, videoWidget
41 #include "components/controller.hpp"            // controllers
42 #include "components/playlist/playlist.hpp"     // plWidget
43 #include "dialogs/firstrun.hpp"                 // First Run
44
45 #include "menus.hpp"                            // Menu creation
46 #include "recents.hpp"                          // RecentItems when DnD
47
48 #include <QCloseEvent>
49 #include <QKeyEvent>
50
51 #include <QUrl>
52 #include <QSize>
53 #include <QDate>
54
55 #include <QMenu>
56 #include <QMenuBar>
57 #include <QStatusBar>
58 #include <QLabel>
59 #include <QStackedWidget>
60
61 #include <vlc_keys.h>                       /* Wheel event */
62 #include <vlc_vout_display.h>               /* vout_thread_t and VOUT_ events */
63
64 // #define DEBUG_INTF
65
66 /* Callback prototypes */
67 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
68                         vlc_value_t old_val, vlc_value_t new_val, void *param );
69 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
70                        vlc_value_t old_val, vlc_value_t new_val, void *param );
71 static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
72                        vlc_value_t old_val, vlc_value_t new_val, void *param );
73 static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
74                            vlc_value_t old_val, vlc_value_t new_val,
75                            void *param );
76
77 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
78 {
79     /* Variables initialisation */
80     bgWidget             = NULL;
81     videoWidget          = NULL;
82     playlistWidget       = NULL;
83     stackCentralOldWidget= NULL;
84     sysTray              = NULL;
85     fullscreenControls   = NULL;
86     cryptedLabel         = NULL;
87     controls             = NULL;
88     inputC               = NULL;
89
90     b_hideAfterCreation  = false; // --qt-start-minimized
91     playlistVisible      = false;
92     input_name           = "";
93     b_interfaceFullScreen= false;
94     b_hasPausedWhenMinimized = false;
95
96
97     /* Ask for Privacy */
98     FirstRun::CheckAndRun( this, p_intf );
99
100     /**
101      *  Configuration and settings
102      *  Pre-building of interface
103      **/
104     /* Main settings */
105     setFocusPolicy( Qt::StrongFocus );
106     setAcceptDrops( true );
107     setWindowRole( "vlc-main" );
108     setWindowIcon( QApplication::windowIcon() );
109     setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
110 #ifdef Q_WS_MAC
111     setAttribute( Qt::WA_MacBrushedMetal );
112 #endif
113
114     /* Is video in embedded in the UI or not */
115     b_videoEmbedded = var_InheritBool( p_intf, "embedded-video" );
116
117     /* Does the interface resize to video size or the opposite */
118     b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
119
120     /* Are we in the enhanced always-video mode or not ? */
121     b_minimalView = var_InheritBool( p_intf, "qt-minimal-view" );
122
123     /* Do we want anoying popups or not */
124     b_notificationEnabled = var_InheritBool( p_intf, "qt-notification" );
125
126     /* */
127     b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
128
129     /* Set the other interface settings */
130     settings = getSettings();
131
132 #ifdef WIN32
133     /* Volume keys */
134     p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" );
135 #endif
136
137     /* */
138     b_plDocked = getSettings()->value( "MainWindow/pl-dock-status", true ).toBool();
139
140
141     /**************************
142      *  UI and Widgets design
143      **************************/
144     setVLCWindowsTitle();
145
146     /************
147      * Menu Bar *
148      ************/
149     QVLCMenuManager::createMenuBar( this, p_intf );
150     CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
151              this, destroyPopupMenu() );
152
153     createMainWidget( settings );
154
155     /**************
156      * Status Bar *
157      **************/
158     createStatusBar();
159     setStatusBarVisibility( getSettings()->value( "MainWindow/status-bar-visible", false ).toBool() );
160
161     /********************
162      * Input Manager    *
163      ********************/
164     MainInputManager::getInstance( p_intf );
165
166 #ifdef WIN32
167     himl = NULL;
168     p_taskbl = NULL;
169     taskbar_wmsg = RegisterWindowMessage("TaskbarButtonCreated");
170 #endif
171
172     /*********************************
173      * Create the Systray Management *
174      *********************************/
175     initSystray();
176
177     /*************************************************************
178      * Connect the input manager to the GUI elements it manages  *
179      * Beware initSystray did some connects on input manager too *
180      *************************************************************/
181     /**
182      * Connects on nameChanged()
183      * Those connects are different because options can impeach them to trigger.
184      **/
185     /* Main Interface statusbar */
186     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
187              this, setName( const QString& ) );
188     /* and title of the Main Interface*/
189     if( var_InheritBool( p_intf, "qt-name-in-title" ) )
190     {
191         CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
192                  this, setVLCWindowsTitle( const QString& ) );
193     }
194     /* END CONNECTS ON IM */
195
196     /* VideoWidget connects for asynchronous calls */
197     b_videoFullScreen = false;
198     connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
199              this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
200              Qt::BlockingQueuedConnection );
201     connect( this, SIGNAL(askReleaseVideo( void )),
202              this, SLOT(releaseVideoSlot( void )),
203              Qt::BlockingQueuedConnection );
204     CONNECT( this, askVideoOnTop(bool), this, setVideoOnTop(bool));
205
206     if( videoWidget )
207     {
208         if( b_autoresize )
209         {
210             CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
211                      this, setVideoSize( unsigned int, unsigned int ) );
212             CONNECT( videoWidget, sizeChanged( int, int ),
213                      this, resizeStack( int,  int ) );
214         }
215         CONNECT( this, askVideoSetFullScreen( bool ),
216                  this, setVideoFullScreen( bool ) );
217     }
218
219     CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
220
221     CONNECT( this, askToQuit(), THEDP, quit() );
222
223     CONNECT( this, askBoss(), this, setBoss() );
224     CONNECT( this, askRaise(), this, setRaise() );
225
226     /** END of CONNECTS**/
227
228
229     /************
230      * Callbacks
231      ************/
232     var_AddCallback( p_intf->p_libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
233     var_AddCallback( p_intf->p_libvlc, "intf-boss", IntfBossCB, p_intf );
234     var_AddCallback( p_intf->p_libvlc, "intf-show", IntfRaiseMainCB, p_intf );
235
236     /* Register callback for the intf-popupmenu variable */
237     var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
238
239
240     /* Final Sizing, restoration and placement of the interface */
241     if( settings->value( "MainWindow/playlist-visible", false ).toBool() )
242         togglePlaylist();
243
244     QVLCTools::restoreWidgetPosition( settings, this, QSize(600, 420) );
245
246     b_interfaceFullScreen = isFullScreen();
247
248     setVisible( !b_hideAfterCreation );
249
250     computeMinimumSize();
251
252     /* Switch to minimal view if needed, must be called after the show() */
253     if( b_minimalView )
254         toggleMinimalView( true );
255 }
256
257 MainInterface::~MainInterface()
258 {
259     /* Unsure we hide the videoWidget before destroying it */
260     if( stackCentralOldWidget == videoWidget )
261         showTab( bgWidget );
262
263     if( videoWidget )
264         releaseVideoSlot();
265
266 #ifdef WIN32
267     if( himl )
268         ImageList_Destroy( himl );
269     if(p_taskbl)
270         p_taskbl->vt->Release(p_taskbl);
271     CoUninitialize();
272 #endif
273
274     /* Be sure to kill the actionsManager... Only used in the MI and control */
275     ActionsManager::killInstance();
276
277     /* Idem */
278     ExtensionsManager::killInstance();
279
280     /* Delete the FSC controller */
281     delete fullscreenControls;
282
283     /* Save states */
284
285     settings->beginGroup("MainWindow");
286     settings->setValue( "pl-dock-status", b_plDocked );
287     /* Save playlist state */
288     if( playlistWidget )
289         settings->setValue( "playlist-visible", playlistVisible );
290
291     settings->setValue( "adv-controls",
292                         getControlsVisibilityStatus() & CONTROLS_ADVANCED );
293     settings->setValue( "status-bar-visible", b_statusbarVisible );
294
295     /* Save the stackCentralW sizes */
296     settings->setValue( "bgSize", stackWidgetsSizes[bgWidget] );
297     settings->setValue( "playlistSize", stackWidgetsSizes[playlistWidget] );
298     settings->endGroup();
299
300     /* Save this size */
301     QVLCTools::saveWidgetPosition(settings, this);
302
303     /* Save undocked playlist size */
304     if( playlistWidget && !isPlDocked() )
305         QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
306
307     delete playlistWidget;
308
309     delete statusBar();
310
311     /* Unregister callbacks */
312     var_DelCallback( p_intf->p_libvlc, "intf-boss", IntfBossCB, p_intf );
313     var_DelCallback( p_intf->p_libvlc, "intf-show", IntfRaiseMainCB, p_intf );
314     var_DelCallback( p_intf->p_libvlc, "intf-toggle-fscontrol", IntfShowCB, p_intf );
315     var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
316
317     p_intf->p_sys->p_mi = NULL;
318 }
319
320 void MainInterface::computeMinimumSize()
321 {
322     int minWidth = 30;
323     if( menuBar()->isVisible() )
324         minWidth += __MAX( controls->sizeHint().width(), menuBar()->sizeHint().width() );
325
326     setMinimumWidth( minWidth );
327 }
328
329 /*****************************
330  *   Main UI handling        *
331  *****************************/
332 void MainInterface::recreateToolbars()
333 {
334     bool b_adv = getControlsVisibilityStatus() & CONTROLS_ADVANCED;
335
336     delete controls;
337     delete inputC;
338
339     controls = new ControlsWidget( p_intf, b_adv, this );
340     inputC = new InputControlsWidget( p_intf, this );
341     mainLayout->insertWidget( 2, inputC );
342     mainLayout->insertWidget( settings->value( "MainWindow/ToolbarPos", 0 ).toInt() ? 0: 3,
343                               controls );
344
345     if( fullscreenControls )
346     {
347         delete fullscreenControls;
348         fullscreenControls = new FullscreenControllerWidget( p_intf, this );
349         CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
350                  this, handleKeyPress( QKeyEvent * ) );
351     }
352 }
353
354 void MainInterface::reloadPrefs()
355 {
356     b_notificationEnabled = var_InheritBool( p_intf, "qt-notification" );
357     b_pauseOnMinimize = var_InheritBool( p_intf, "qt-pause-minimized" );
358 #ifdef WIN32
359     p_intf->p_sys->disable_volume_keys = var_InheritBool( p_intf, "qt-disable-volume-keys" );
360 #endif
361     if( !var_InheritBool( p_intf, "qt-fs-controller" ) && fullscreenControls )
362     {
363         delete fullscreenControls;
364         fullscreenControls = NULL;
365     }
366 }
367
368 void MainInterface::createMainWidget( QSettings *settings )
369 {
370     /* Create the main Widget and the mainLayout */
371     QWidget *main = new QWidget;
372     setCentralWidget( main );
373     mainLayout = new QVBoxLayout( main );
374     main->setContentsMargins( 0, 0, 0, 0 );
375     mainLayout->setSpacing( 0 ); mainLayout->setMargin( 0 );
376
377     /* */
378     stackCentralW = new QVLCStackedWidget( main );
379
380     /* Bg Cone */
381     bgWidget = new BackgroundWidget( p_intf );
382     stackCentralW->addWidget( bgWidget );
383     if ( !var_InheritBool( p_intf, "qt-bgcone" ) )
384         bgWidget->setWithArt( false );
385     else
386         if ( var_InheritBool( p_intf, "qt-bgcone-expands" ) )
387             bgWidget->setExpandstoHeight( true );
388
389     /* And video Outputs */
390     if( b_videoEmbedded )
391     {
392         videoWidget = new VideoWidget( p_intf );
393         stackCentralW->addWidget( videoWidget );
394     }
395     mainLayout->insertWidget( 1, stackCentralW );
396
397     stackWidgetsSizes[bgWidget] = settings->value( "MainWindow/bgSize", QSize( 600, 0 ) ).toSize();
398     /* Resize even if no-auto-resize, because we are at creation */
399     resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
400
401     /* Create the CONTROLS Widget */
402     controls = new ControlsWidget( p_intf,
403                    settings->value( "MainWindow/adv-controls", false ).toBool(), this );
404     inputC = new InputControlsWidget( p_intf, this );
405
406     mainLayout->insertWidget( 2, inputC );
407     mainLayout->insertWidget( settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
408                               controls );
409
410     /* Visualisation, disabled for now, they SUCK */
411     #if 0
412     visualSelector = new VisualSelector( p_intf );
413     mainLayout->insertWidget( 0, visualSelector );
414     visualSelector->hide();
415     #endif
416
417
418     /* Enable the popup menu in the MI */
419     main->setContextMenuPolicy( Qt::CustomContextMenu );
420     CONNECT( main, customContextMenuRequested( const QPoint& ),
421              this, popupMenu( const QPoint& ) );
422
423     if ( depth() > 8 ) /* 8bit depth has too many issues with opacity */
424         /* Create the FULLSCREEN CONTROLS Widget */
425         if( var_InheritBool( p_intf, "qt-fs-controller" ) )
426         {
427             fullscreenControls = new FullscreenControllerWidget( p_intf, this );
428             CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
429                      this, handleKeyPress( QKeyEvent * ) );
430         }
431 }
432
433 inline void MainInterface::initSystray()
434 {
435     bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
436     bool b_systrayWanted = var_InheritBool( p_intf, "qt-system-tray" );
437
438     if( var_InheritBool( p_intf, "qt-start-minimized") )
439     {
440         if( b_systrayAvailable )
441         {
442             b_systrayWanted = true;
443             b_hideAfterCreation = true;
444         }
445         else
446             msg_Err( p_intf, "cannot start minimized without system tray bar" );
447     }
448
449     if( b_systrayAvailable && b_systrayWanted )
450         createSystray();
451 }
452
453 inline void MainInterface::createStatusBar()
454 {
455     /****************
456      *  Status Bar  *
457      ****************/
458     /* Widgets Creation*/
459     QStatusBar *statusBarr = statusBar();
460
461     TimeLabel *timeLabel = new TimeLabel( p_intf );
462     nameLabel = new QLabel( this );
463     nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
464                                       | Qt::TextSelectableByKeyboard );
465     SpeedLabel *speedLabel = new SpeedLabel( p_intf, this );
466
467     /* Styling those labels */
468     timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
469     speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
470     nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
471     timeLabel->setStyleSheet(
472             "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
473     speedLabel->setStyleSheet(
474             "QLabel:hover { background-color: rgba(255, 255, 255, 50%) }" );
475     /* pad both label and its tooltip */
476     nameLabel->setStyleSheet( "padding-left: 5px; padding-right: 5px;" );
477
478     /* and adding those */
479     statusBarr->addWidget( nameLabel, 8 );
480     statusBarr->addPermanentWidget( speedLabel, 0 );
481     statusBarr->addPermanentWidget( timeLabel, 0 );
482
483     /* timeLabel behaviour:
484        - double clicking opens the goto time dialog
485        - right-clicking and clicking just toggle between remaining and
486          elapsed time.*/
487     CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
488
489     CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
490              this, showCryptedLabel( bool ) );
491
492     CONNECT( THEMIM->getIM(), seekRequested( float ),
493              timeLabel, setDisplayPosition( float ) );
494
495     /* This shouldn't be necessary, but for somehow reason, the statusBarr
496        starts at height of 20px and when a text is shown it needs more space.
497        But, as the QMainWindow policy doesn't allow statusBar to change QMW's
498        geometry, we need to force a height. If you have a better idea, please
499        tell me -- jb
500      */
501     statusBarr->setFixedHeight( statusBarr->sizeHint().height() + 2 );
502 }
503
504 /**********************************************************************
505  * Handling of sizing of the components
506  **********************************************************************/
507
508 void MainInterface::debug()
509 {
510 #ifdef DEBUG_INTF
511     msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
512     msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
513     msg_Dbg( p_intf, "minimumsize: %i - %i", minimumSize().height(), minimumSize().width() );
514
515     msg_Dbg( p_intf, "Stack size: %i - %i", stackCentralW->size().height(), stackCentralW->size().width() );
516     msg_Dbg( p_intf, "Stack sizeHint: %i - %i", stackCentralW->sizeHint().height(), stackCentralW->sizeHint().width() );
517     msg_Dbg( p_intf, "Central size: %i - %i", centralWidget()->size().height(), centralWidget()->size().width() );
518 #endif
519 }
520
521 inline void MainInterface::showVideo() { showTab( videoWidget ); }
522 inline void MainInterface::restoreStackOldWidget()
523             { showTab( stackCentralOldWidget ); }
524
525 inline void MainInterface::showTab( QWidget *widget )
526 {
527 #ifdef DEBUG_INTF
528     msg_Warn( p_intf, "Old stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
529 #endif
530
531     stackCentralOldWidget = stackCentralW->currentWidget();
532     stackWidgetsSizes[stackCentralOldWidget] = stackCentralW->size();
533
534     /* If we are playing video, embedded */
535     if( videoWidget && THEMIM->getIM()->hasVideo() )
536     {
537         /* Video -> Playlist */
538         if( videoWidget == stackCentralOldWidget && widget == playlistWidget )
539         {
540             stackCentralW->removeWidget( videoWidget );
541             videoWidget->show(); videoWidget->raise();
542         }
543
544         /* Playlist -> Video */
545         if( playlistWidget == stackCentralOldWidget && widget == videoWidget )
546         {
547             playlistWidget->artContainer->removeWidget( videoWidget );
548             videoWidget->show(); videoWidget->raise();
549             stackCentralW->addWidget( videoWidget );
550         }
551     }
552
553     stackCentralW->setCurrentWidget( widget );
554     if( b_autoresize )
555         resizeStack( stackWidgetsSizes[widget].width(), stackWidgetsSizes[widget].height() );
556
557 #ifdef DEBUG_INTF
558     msg_Warn( p_intf, "State change %i",  stackCentralW->currentIndex() );
559     msg_Warn( p_intf, "New stackCentralOldWidget %i", stackCentralW->indexOf( stackCentralOldWidget ) );
560 #endif
561
562     /* This part is done later, to account for the new pl size */
563     if( videoWidget && THEMIM->getIM()->hasVideo() &&
564         videoWidget == stackCentralOldWidget && widget == playlistWidget )
565     {
566         playlistWidget->artContainer->addWidget( videoWidget );
567         playlistWidget->artContainer->setCurrentWidget( videoWidget );
568     }
569 }
570
571 void MainInterface::destroyPopupMenu()
572 {
573     QVLCMenuManager::PopupMenu( p_intf, false );
574 }
575
576 void MainInterface::popupMenu( const QPoint & )
577 {
578     QVLCMenuManager::PopupMenu( p_intf, true );
579 }
580
581 void MainInterface::toggleFSC()
582 {
583    if( !fullscreenControls ) return;
584
585    IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type );
586    QApplication::postEvent( fullscreenControls, eShow );
587 }
588
589 /****************************************************************************
590  * Video Handling
591  ****************************************************************************/
592
593 /**
594  * NOTE:
595  * You must not change the state of this object or other Qt4 UI objects,
596  * from the video output thread - only from the Qt4 UI main loop thread.
597  * All window provider queries must be handled through signals or events.
598  * That's why we have all those emit statements...
599  */
600 WId MainInterface::getVideo( int *pi_x, int *pi_y,
601                              unsigned int *pi_width, unsigned int *pi_height )
602 {
603     if( !videoWidget )
604         return 0;
605
606     /* This is a blocking call signal. Results are returned through pointers.
607      * Beware of deadlocks! */
608     WId id;
609     emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
610     return id;
611 }
612
613 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
614                                   unsigned *pi_width, unsigned *pi_height )
615 {
616     /* Hidden or minimized, activate */
617     if( isHidden() || isMinimized() )
618         toggleUpdateSystrayMenu();
619
620     /* Request the videoWidget */
621     WId ret = videoWidget->request( pi_x, pi_y,
622                                     pi_width, pi_height, !b_autoresize );
623     *p_id = ret;
624     if( ret ) /* The videoWidget is available */
625     {
626         /* Consider the video active now */
627         showVideo();
628
629         /* Ask videoWidget to resize correctly, if we are in normal mode */
630         if( !isFullScreen() && !isMaximized() && b_autoresize )
631             videoWidget->SetSizing( *pi_width, *pi_height );
632     }
633 }
634
635 /* Asynchronous call from the WindowClose function */
636 void MainInterface::releaseVideo( void )
637 {
638     emit askReleaseVideo();
639 }
640
641 /* Function that is CONNECTED to the previous emit */
642 void MainInterface::releaseVideoSlot( void )
643 {
644     /* This function is called when the embedded video window is destroyed,
645      * or in the rare case that the embedded window is still here but the
646      * Qt4 interface exits. */
647     assert( videoWidget );
648     videoWidget->release();
649     setVideoOnTop( false );
650     setVideoFullScreen( false );
651
652     if( stackCentralW->currentWidget() == videoWidget )
653         restoreStackOldWidget();
654     else if( playlistWidget &&
655              playlistWidget->artContainer->currentWidget() == videoWidget )
656     {
657         playlistWidget->artContainer->setCurrentIndex( 0 );
658         stackCentralW->addWidget( videoWidget );
659     }
660
661     /* We don't want to have a blank video to popup */
662     stackCentralOldWidget = bgWidget;
663 }
664
665 void MainInterface::setVideoSize( unsigned int w, unsigned int h )
666 {
667     if( !isFullScreen() && !isMaximized() )
668         videoWidget->SetSizing( w, h );
669 }
670
671 void MainInterface::setVideoFullScreen( bool fs )
672 {
673     b_videoFullScreen = fs;
674     if( fs )
675     {
676         int numscreen = var_InheritInteger( p_intf, "qt-fullscreen-screennumber" );
677         /* if user hasn't defined screennumber, or screennumber that is bigger
678          * than current number of screens, take screennumber where current interface
679          * is
680          */
681         if( numscreen == -1 || numscreen > QApplication::desktop()->numScreens() )
682             numscreen = QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi );
683
684         QRect screenres = QApplication::desktop()->screenGeometry( numscreen );
685
686         /* To be sure window is on proper-screen in xinerama */
687         if( !screenres.contains( pos() ) )
688         {
689             msg_Dbg( p_intf, "Moving video to correct screen");
690             move( QPoint( screenres.x(), screenres.y() ) );
691         }
692
693         /* */
694         if( playlistWidget->artContainer->currentWidget() == videoWidget )
695         {
696             showTab( videoWidget );
697         }
698
699         /* */
700         setMinimalView( true );
701         setInterfaceFullScreen( true );
702     }
703     else
704     {
705         /* TODO do we want to restore screen and position ? (when
706          * qt-fullscreen-screennumber is forced) */
707         setMinimalView( b_minimalView );
708         setInterfaceFullScreen( b_interfaceFullScreen );
709     }
710     videoWidget->sync();
711 }
712
713 /* Slot to change the video always-on-top flag.
714  * Emit askVideoOnTop() to invoke this from other thread. */
715 void MainInterface::setVideoOnTop( bool on_top )
716 {
717     Qt::WindowFlags oldflags = windowFlags(), newflags;
718
719     if( on_top )
720         newflags = oldflags | Qt::WindowStaysOnTopHint;
721     else
722         newflags = oldflags & ~Qt::WindowStaysOnTopHint;
723     if( newflags != oldflags && !b_videoFullScreen )
724
725     {
726         setWindowFlags( newflags );
727         show(); /* necessary to apply window flags */
728     }
729 }
730
731 /* Asynchronous call from WindowControl function */
732 int MainInterface::controlVideo( int i_query, va_list args )
733 {
734     switch( i_query )
735     {
736     case VOUT_WINDOW_SET_SIZE:
737     {
738         unsigned int i_width  = va_arg( args, unsigned int );
739         unsigned int i_height = va_arg( args, unsigned int );
740
741         emit askVideoToResize( i_width, i_height );
742         return VLC_SUCCESS;
743     }
744     case VOUT_WINDOW_SET_STATE:
745     {
746         unsigned i_arg = va_arg( args, unsigned );
747         unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
748
749         emit askVideoOnTop( on_top != 0 );
750         return VLC_SUCCESS;
751     }
752     case VOUT_WINDOW_SET_FULLSCREEN:
753     {
754         bool b_fs = va_arg( args, int );
755
756         emit askVideoSetFullScreen( b_fs );
757         return VLC_SUCCESS;
758     }
759     default:
760         msg_Warn( p_intf, "unsupported control query" );
761         return VLC_EGENERIC;
762     }
763 }
764
765 /*****************************************************************************
766  * Playlist, Visualisation and Menus handling
767  *****************************************************************************/
768 /**
769  * Toggle the playlist widget or dialog
770  **/
771 void MainInterface::createPlaylist()
772 {
773     playlistWidget = new PlaylistWidget( p_intf, this );
774
775     if( b_plDocked )
776     {
777         stackCentralW->addWidget( playlistWidget );
778         stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 600, 300 ) ).toSize();
779     }
780     else
781     {
782 #ifdef WIN32
783         playlistWidget->setParent( NULL );
784 #endif
785         playlistWidget->setWindowFlags( Qt::Window );
786
787         /* This will restore the geometry but will not work for position,
788            because of parenting */
789         QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
790                 playlistWidget, QSize( 600, 300 ) );
791     }
792 }
793
794 void MainInterface::togglePlaylist()
795 {
796     if( !playlistWidget )
797     {
798         createPlaylist();
799     }
800
801     if( b_plDocked )
802     {
803         /* Playlist is not visible, show it */
804         if( stackCentralW->currentWidget() != playlistWidget )
805         {
806             showTab( playlistWidget );
807         }
808         else /* Hide it! */
809         {
810             restoreStackOldWidget();
811         }
812         playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
813     }
814     else
815     {
816 #ifdef WIN32
817         playlistWidget->setParent( NULL );
818 #endif
819         playlistWidget->setWindowFlags( Qt::Window );
820         playlistVisible = !playlistVisible;
821         playlistWidget->setVisible( playlistVisible );
822     }
823     debug();
824 }
825
826 void MainInterface::dockPlaylist( bool p_docked )
827 {
828     if( b_plDocked == p_docked ) return;
829     b_plDocked = p_docked;
830
831     if( !playlistWidget ) return; /* Playlist wasn't created yet */
832     if( !p_docked )
833     {
834         stackCentralW->removeWidget( playlistWidget );
835 #ifdef WIN32
836         playlistWidget->setParent( NULL );
837 #endif
838         playlistWidget->setWindowFlags( Qt::Window );
839         QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
840                 playlistWidget, QSize( 600, 300 ) );
841         playlistWidget->show();
842         restoreStackOldWidget();
843     }
844     else
845     {
846         QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
847         playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
848         // It would be logical that QStackWidget::addWidget reset the flags...
849         stackCentralW->addWidget( playlistWidget );
850         showTab( playlistWidget );
851     }
852     playlistVisible = true;
853 }
854
855 /*
856  * setMinimalView is the private function used by
857  * the SLOT toggleMinimalView and setVideoFullScreen
858  */
859 void MainInterface::setMinimalView( bool b_minimal )
860 {
861     menuBar()->setVisible( !b_minimal );
862     controls->setVisible( !b_minimal );
863     statusBar()->setVisible( !b_minimal && b_statusbarVisible );
864     inputC->setVisible( !b_minimal );
865 }
866
867 /*
868  * This public SLOT is used for moving to minimal View Mode
869  *
870  * If b_minimal is false, then we are normalView
871  */
872 void MainInterface::toggleMinimalView( bool b_minimal )
873 {
874     if( !b_minimalView && b_autoresize ) /* Normal mode */
875     {
876         if( stackCentralW->currentWidget() == bgWidget )
877         {
878             if( stackCentralW->height() < 16 )
879             {
880                 resizeStack( stackCentralW->width(), 100 );
881             }
882         }
883     }
884     b_minimalView = b_minimal;
885     if( !b_videoFullScreen )
886     {
887         setMinimalView( b_minimalView );
888         computeMinimumSize();
889     }
890
891     emit minimalViewToggled( b_minimalView );
892 }
893
894 /* toggling advanced controls buttons */
895 void MainInterface::toggleAdvancedButtons()
896 {
897     controls->toggleAdvanced();
898 //    if( fullscreenControls ) fullscreenControls->toggleAdvanced();
899 }
900
901 /* Get the visibility status of the controls (hidden or not, advanced or not) */
902 int MainInterface::getControlsVisibilityStatus()
903 {
904     if( !controls ) return 0;
905     return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
906                 + CONTROLS_ADVANCED * controls->b_advancedVisible );
907 }
908
909 void MainInterface::setStatusBarVisibility( bool b_visible )
910 {
911     statusBar()->setVisible( b_visible );
912     b_statusbarVisible = b_visible;
913     if( controls ) controls->setGripVisible( !b_statusbarVisible );
914 }
915
916 #if 0
917 void MainInterface::visual()
918 {
919     if( !VISIBLE( visualSelector) )
920     {
921         visualSelector->show();
922         if( !THEMIM->getIM()->hasVideo() )
923         {
924             /* Show the background widget */
925         }
926         visualSelectorEnabled = true;
927     }
928     else
929     {
930         /* Stop any currently running visualization */
931         visualSelector->hide();
932         visualSelectorEnabled = false;
933     }
934 }
935 #endif
936
937 /************************************************************************
938  * Other stuff
939  ************************************************************************/
940 void MainInterface::setName( const QString& name )
941 {
942     input_name = name; /* store it for the QSystray use */
943     /* Display it in the status bar, but also as a Tooltip in case it doesn't
944        fit in the label */
945     nameLabel->setText( name );
946     nameLabel->setToolTip( name );
947 }
948
949 /**
950  * Give the decorations of the Main Window a correct Name.
951  * If nothing is given, set it to VLC...
952  **/
953 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
954 {
955     if( aTitle.isEmpty() )
956     {
957         setWindowTitle( qtr( "VLC media player" ) );
958     }
959     else
960     {
961         setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
962     }
963 }
964
965 void MainInterface::showCryptedLabel( bool b_show )
966 {
967     if( cryptedLabel == NULL )
968     {
969         cryptedLabel = new QLabel;
970         // The lock icon is not the right one for DRM protection/scrambled.
971         //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
972         cryptedLabel->setText( "DRM" );
973         statusBar()->addWidget( cryptedLabel );
974     }
975
976     cryptedLabel->setVisible( b_show );
977 }
978
979 void MainInterface::showBuffering( float f_cache )
980 {
981     QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
982     statusBar()->showMessage( amount, 1000 );
983 }
984
985 /*****************************************************************************
986  * Systray Icon and Systray Menu
987  *****************************************************************************/
988 /**
989  * Create a SystemTray icon and a menu that would go with it.
990  * Connects to a click handler on the icon.
991  **/
992 void MainInterface::createSystray()
993 {
994     QIcon iconVLC;
995     if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
996         iconVLC =  QIcon( ":/logo/vlc128-xmas.png" );
997     else
998         iconVLC =  QIcon( ":/logo/vlc128.png" );
999     sysTray = new QSystemTrayIcon( iconVLC, this );
1000     sysTray->setToolTip( qtr( "VLC media player" ));
1001
1002     systrayMenu = new QMenu( qtr( "VLC media player" ), this );
1003     systrayMenu->setIcon( iconVLC );
1004
1005     QVLCMenuManager::updateSystrayMenu( this, p_intf, true );
1006     sysTray->show();
1007
1008     CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
1009              this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
1010
1011     /* Connects on nameChanged() */
1012     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
1013              this, updateSystrayTooltipName( const QString& ) );
1014     /* Connect PLAY_STATUS on the systray */
1015     CONNECT( THEMIM->getIM(), playingStatusChanged( int ),
1016              this, updateSystrayTooltipStatus( int ) );
1017 }
1018
1019 /**
1020  * Updates the Systray Icon's menu and toggle the main interface
1021  */
1022 void MainInterface::toggleUpdateSystrayMenu()
1023 {
1024     /* If hidden, show it */
1025     if( isHidden() )
1026     {
1027         show();
1028         activateWindow();
1029     }
1030     else if( isMinimized() )
1031     {
1032         /* Minimized */
1033         showNormal();
1034         activateWindow();
1035     }
1036     else
1037     {
1038         /* Visible (possibly under other windows) */
1039 #ifdef WIN32
1040         /* check if any visible window is above vlc in the z-order,
1041          * but ignore the ones always on top
1042          * and the ones which can't be activated */
1043         WINDOWINFO wi;
1044         HWND hwnd;
1045         wi.cbSize = sizeof( WINDOWINFO );
1046         for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
1047                 hwnd && ( !IsWindowVisible( hwnd ) ||
1048                     ( GetWindowInfo( hwnd, &wi ) &&
1049                       (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
1050                 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
1051             if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
1052                 (wi.dwExStyle&WS_EX_TOPMOST) )
1053             {
1054                 hide();
1055             }
1056             else
1057             {
1058                 activateWindow();
1059             }
1060 #else
1061         hide();
1062 #endif
1063     }
1064     if( sysTray )
1065         QVLCMenuManager::updateSystrayMenu( this, p_intf );
1066 }
1067
1068 /* First Item of the systray menu */
1069 void MainInterface::showUpdateSystrayMenu()
1070 {
1071     if( isHidden() )
1072         show();
1073     if( isMinimized() )
1074         showNormal();
1075     activateWindow();
1076
1077     QVLCMenuManager::updateSystrayMenu( this, p_intf );
1078 }
1079
1080 /* First Item of the systray menu */
1081 void MainInterface::hideUpdateSystrayMenu()
1082 {
1083     hide();
1084     QVLCMenuManager::updateSystrayMenu( this, p_intf );
1085 }
1086
1087 /* Click on systray Icon */
1088 void MainInterface::handleSystrayClick(
1089                                     QSystemTrayIcon::ActivationReason reason )
1090 {
1091     switch( reason )
1092     {
1093         case QSystemTrayIcon::Trigger:
1094         case QSystemTrayIcon::DoubleClick:
1095 #ifdef Q_WS_MAC
1096             QVLCMenuManager::updateSystrayMenu( this, p_intf );
1097 #else
1098             toggleUpdateSystrayMenu();
1099 #endif
1100             break;
1101         case QSystemTrayIcon::MiddleClick:
1102             sysTray->showMessage( qtr( "VLC media player" ),
1103                     qtr( "Control menu for the player" ),
1104                     QSystemTrayIcon::Information, 3000 );
1105             break;
1106         default:
1107             break;
1108     }
1109 }
1110
1111 /**
1112  * Updates the name of the systray Icon tooltip.
1113  * Doesn't check if the systray exists, check before you call it.
1114  **/
1115 void MainInterface::updateSystrayTooltipName( const QString& name )
1116 {
1117     if( name.isEmpty() )
1118     {
1119         sysTray->setToolTip( qtr( "VLC media player" ) );
1120     }
1121     else
1122     {
1123         sysTray->setToolTip( name );
1124         if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1125         {
1126             sysTray->showMessage( qtr( "VLC media player" ), name,
1127                     QSystemTrayIcon::NoIcon, 3000 );
1128         }
1129     }
1130
1131     QVLCMenuManager::updateSystrayMenu( this, p_intf );
1132 }
1133
1134 /**
1135  * Updates the status of the systray Icon tooltip.
1136  * Doesn't check if the systray exists, check before you call it.
1137  **/
1138 void MainInterface::updateSystrayTooltipStatus( int i_status )
1139 {
1140     switch( i_status )
1141     {
1142     case PLAYING_S:
1143         sysTray->setToolTip( input_name );
1144         break;
1145     case PAUSE_S:
1146         sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1147         break;
1148     default:
1149         sysTray->setToolTip( qtr( "VLC media player" ) );
1150         break;
1151     }
1152     QVLCMenuManager::updateSystrayMenu( this, p_intf );
1153 }
1154
1155 void MainInterface::changeEvent(QEvent *event)
1156 {
1157     if( event->type() == QEvent::WindowStateChange )
1158     {
1159         QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
1160         Qt::WindowStates newState = windowState();
1161         Qt::WindowStates oldState = windowStateChangeEvent->oldState();
1162
1163         if( newState & Qt::WindowMinimized )
1164         {
1165             b_hasPausedWhenMinimized = false;
1166
1167             if( THEMIM->getIM()->playingStatus() == PLAYING_S &&
1168                 THEMIM->getIM()->hasVideo() && !THEMIM->getIM()->hasVisualisation() &&
1169                 b_pauseOnMinimize )
1170             {
1171                 b_hasPausedWhenMinimized = true;
1172                 THEMIM->pause();
1173             }
1174         }
1175         else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
1176         {
1177             if( b_hasPausedWhenMinimized )
1178             {
1179                 THEMIM->play();
1180             }
1181         }
1182     }
1183
1184     QWidget::changeEvent(event);
1185 }
1186
1187 /************************************************************************
1188  * D&D Events
1189  ************************************************************************/
1190 void MainInterface::dropEvent(QDropEvent *event)
1191 {
1192     dropEventPlay( event, true );
1193 }
1194
1195 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1196 {
1197     if( event->possibleActions() & ( Qt::CopyAction | Qt::MoveAction ) )
1198        event->setDropAction( Qt::CopyAction );
1199     else
1200         return;
1201
1202     const QMimeData *mimeData = event->mimeData();
1203
1204     /* D&D of a subtitles file, add it on the fly */
1205     if( mimeData->urls().count() == 1 && THEMIM->getIM()->hasInput() )
1206     {
1207         if( !input_AddSubtitle( THEMIM->getInput(),
1208                  qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1209                  true ) )
1210         {
1211             event->accept();
1212             return;
1213         }
1214     }
1215
1216     bool first = b_play;
1217     foreach( const QUrl &url, mimeData->urls() )
1218     {
1219         if( url.isValid() )
1220         {
1221             QString mrl = toURI( url.toEncoded().constData() );
1222             playlist_Add( THEPL, qtu(mrl), NULL,
1223                           PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1224                           PLAYLIST_END, true, pl_Unlocked );
1225             first = false;
1226             RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1227         }
1228     }
1229
1230     /* Browsers give content as text if you dnd the addressbar,
1231        so check if mimedata has valid url in text and use it
1232        if we didn't get any normal Urls()*/
1233     if( !mimeData->hasUrls() && mimeData->hasText() &&
1234         QUrl(mimeData->text()).isValid() )
1235     {
1236         QString mrl = toURI( mimeData->text() );
1237         playlist_Add( THEPL, qtu(mrl), NULL,
1238                       PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1239                       PLAYLIST_END, true, pl_Unlocked );
1240     }
1241     event->accept();
1242 }
1243 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1244 {
1245      event->acceptProposedAction();
1246 }
1247 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1248 {
1249      event->acceptProposedAction();
1250 }
1251 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1252 {
1253      event->accept();
1254 }
1255
1256 /************************************************************************
1257  * Events stuff
1258  ************************************************************************/
1259 void MainInterface::keyPressEvent( QKeyEvent *e )
1260 {
1261     handleKeyPress( e );
1262 }
1263
1264 void MainInterface::handleKeyPress( QKeyEvent *e )
1265 {
1266     if( ( e->modifiers() &  Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1267     {
1268         toggleMinimalView( !b_minimalView );
1269         e->accept();
1270     }
1271
1272     int i_vlck = qtEventToVLCKey( e );
1273     if( i_vlck > 0 )
1274     {
1275         var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1276         e->accept();
1277     }
1278     else
1279         e->ignore();
1280 }
1281
1282 void MainInterface::wheelEvent( QWheelEvent *e )
1283 {
1284     int i_vlckey = qtWheelEventToVLCKey( e );
1285     var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1286     e->accept();
1287 }
1288
1289 void MainInterface::closeEvent( QCloseEvent *e )
1290 {
1291 //  hide();
1292     emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1293     /* Accept session quit. Otherwise we break the desktop mamager. */
1294     e->accept();
1295 }
1296
1297 void MainInterface::setInterfaceFullScreen( bool fs )
1298 {
1299     if( fs )
1300         setWindowState( windowState() | Qt::WindowFullScreen );
1301     else
1302         setWindowState( windowState() & ~Qt::WindowFullScreen );
1303 }
1304 void MainInterface::toggleInterfaceFullScreen()
1305 {
1306     b_interfaceFullScreen = !b_interfaceFullScreen;
1307     if( !b_videoFullScreen )
1308         setInterfaceFullScreen( b_interfaceFullScreen );
1309     emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1310 }
1311
1312 void MainInterface::emitBoss()
1313 {
1314     emit askBoss();
1315 }
1316 void MainInterface::setBoss()
1317 {
1318     THEMIM->pause();
1319     if( sysTray )
1320     {
1321         hide();
1322     }
1323     else
1324     {
1325         showMinimized();
1326     }
1327 }
1328
1329 void MainInterface::emitRaise()
1330 {
1331     emit askRaise();
1332 }
1333 void MainInterface::setRaise()
1334 {
1335     activateWindow();
1336     raise();
1337 }
1338
1339 /*****************************************************************************
1340  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1341  *  We don't show the menu directly here because we don't want the
1342  *  caller to block for a too long time.
1343  *****************************************************************************/
1344 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1345                         vlc_value_t old_val, vlc_value_t new_val, void *param )
1346 {
1347     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1348
1349     intf_thread_t *p_intf = (intf_thread_t *)param;
1350
1351     if( p_intf->pf_show_dialog )
1352     {
1353         p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1354                                 new_val.b_bool, NULL );
1355     }
1356
1357     return VLC_SUCCESS;
1358 }
1359
1360 /*****************************************************************************
1361  * IntfShowCB: callback triggered by the intf-toggle-fscontrol libvlc variable.
1362  *****************************************************************************/
1363 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1364                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1365 {
1366     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1367     VLC_UNUSED( new_val );
1368
1369     intf_thread_t *p_intf = (intf_thread_t *)param;
1370     p_intf->p_sys->p_mi->toggleFSC();
1371
1372     /* Show event */
1373      return VLC_SUCCESS;
1374 }
1375
1376 /*****************************************************************************
1377  * IntfRaiseMainCB: callback triggered by the intf-show-main libvlc variable.
1378  *****************************************************************************/
1379 static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
1380                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1381 {
1382     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1383     VLC_UNUSED( new_val );
1384
1385     intf_thread_t *p_intf = (intf_thread_t *)param;
1386     p_intf->p_sys->p_mi->emitRaise();
1387
1388     return VLC_SUCCESS;
1389 }
1390
1391 /*****************************************************************************
1392  * IntfBossCB: callback triggered by the intf-boss libvlc variable.
1393  *****************************************************************************/
1394 static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
1395                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1396 {
1397     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1398     VLC_UNUSED( new_val );
1399
1400     intf_thread_t *p_intf = (intf_thread_t *)param;
1401     p_intf->p_sys->p_mi->emitBoss();
1402
1403     return VLC_SUCCESS;
1404 }