]> git.sesse.net Git - vlc/blob - modules/gui/qt4/main_interface.cpp
windows: use C++ prototype for REFIID / CoCreateInstance
[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     QVLCMenu::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     QVLCMenu::PopupMenu( p_intf, false );
574 }
575
576 void MainInterface::popupMenu( const QPoint & )
577 {
578     QVLCMenu::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         setMinimalView( true );
693         setInterfaceFullScreen( true );
694     }
695     else
696     {
697         /* TODO do we want to restore screen and position ? (when
698          * qt-fullscreen-screennumber is forced) */
699         setMinimalView( b_minimalView );
700         setInterfaceFullScreen( b_interfaceFullScreen );
701     }
702     videoWidget->sync();
703 }
704
705 /* Slot to change the video always-on-top flag.
706  * Emit askVideoOnTop() to invoke this from other thread. */
707 void MainInterface::setVideoOnTop( bool on_top )
708 {
709     Qt::WindowFlags oldflags = windowFlags(), newflags;
710
711     if( on_top )
712         newflags = oldflags | Qt::WindowStaysOnTopHint;
713     else
714         newflags = oldflags & ~Qt::WindowStaysOnTopHint;
715     if( newflags != oldflags && !b_videoFullScreen )
716
717     {
718         setWindowFlags( newflags );
719         show(); /* necessary to apply window flags */
720     }
721 }
722
723 /* Asynchronous call from WindowControl function */
724 int MainInterface::controlVideo( int i_query, va_list args )
725 {
726     switch( i_query )
727     {
728     case VOUT_WINDOW_SET_SIZE:
729     {
730         unsigned int i_width  = va_arg( args, unsigned int );
731         unsigned int i_height = va_arg( args, unsigned int );
732
733         emit askVideoToResize( i_width, i_height );
734         return VLC_SUCCESS;
735     }
736     case VOUT_WINDOW_SET_STATE:
737     {
738         unsigned i_arg = va_arg( args, unsigned );
739         unsigned on_top = i_arg & VOUT_WINDOW_STATE_ABOVE;
740
741         emit askVideoOnTop( on_top != 0 );
742         return VLC_SUCCESS;
743     }
744     case VOUT_WINDOW_SET_FULLSCREEN:
745     {
746         bool b_fs = va_arg( args, int );
747
748         emit askVideoSetFullScreen( b_fs );
749         return VLC_SUCCESS;
750     }
751     default:
752         msg_Warn( p_intf, "unsupported control query" );
753         return VLC_EGENERIC;
754     }
755 }
756
757 /*****************************************************************************
758  * Playlist, Visualisation and Menus handling
759  *****************************************************************************/
760 /**
761  * Toggle the playlist widget or dialog
762  **/
763 void MainInterface::createPlaylist()
764 {
765     playlistWidget = new PlaylistWidget( p_intf, this );
766
767     if( b_plDocked )
768     {
769         stackCentralW->addWidget( playlistWidget );
770         stackWidgetsSizes[playlistWidget] = settings->value( "playlistSize", QSize( 600, 300 ) ).toSize();
771     }
772     else
773     {
774 #ifdef WIN32
775         playlistWidget->setParent( NULL );
776 #endif
777         playlistWidget->setWindowFlags( Qt::Window );
778
779         /* This will restore the geometry but will not work for position,
780            because of parenting */
781         QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
782                 playlistWidget, QSize( 600, 300 ) );
783     }
784 }
785
786 void MainInterface::togglePlaylist()
787 {
788     if( !playlistWidget )
789     {
790         createPlaylist();
791     }
792
793     if( b_plDocked )
794     {
795         /* Playlist is not visible, show it */
796         if( stackCentralW->currentWidget() != playlistWidget )
797         {
798             showTab( playlistWidget );
799         }
800         else /* Hide it! */
801         {
802             restoreStackOldWidget();
803         }
804         playlistVisible = ( stackCentralW->currentWidget() == playlistWidget );
805     }
806     else
807     {
808 #ifdef WIN32
809         playlistWidget->setParent( NULL );
810 #endif
811         playlistWidget->setWindowFlags( Qt::Window );
812         playlistVisible = !playlistVisible;
813         playlistWidget->setVisible( playlistVisible );
814     }
815     debug();
816 }
817
818 void MainInterface::dockPlaylist( bool p_docked )
819 {
820     if( b_plDocked == p_docked ) return;
821     b_plDocked = p_docked;
822
823     if( !playlistWidget ) return; /* Playlist wasn't created yet */
824     if( !p_docked )
825     {
826         stackCentralW->removeWidget( playlistWidget );
827 #ifdef WIN32
828         playlistWidget->setParent( NULL );
829 #endif
830         playlistWidget->setWindowFlags( Qt::Window );
831         QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
832                 playlistWidget, QSize( 600, 300 ) );
833         playlistWidget->show();
834         restoreStackOldWidget();
835     }
836     else
837     {
838         QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
839         playlistWidget->setWindowFlags( Qt::Widget ); // Probably a Qt bug here
840         // It would be logical that QStackWidget::addWidget reset the flags...
841         stackCentralW->addWidget( playlistWidget );
842         showTab( playlistWidget );
843     }
844     playlistVisible = true;
845 }
846
847 /*
848  * setMinimalView is the private function used by
849  * the SLOT toggleMinimalView and setVideoFullScreen
850  */
851 void MainInterface::setMinimalView( bool b_minimal )
852 {
853     menuBar()->setVisible( !b_minimal );
854     controls->setVisible( !b_minimal );
855     statusBar()->setVisible( !b_minimal && b_statusbarVisible );
856     inputC->setVisible( !b_minimal );
857 }
858
859 /*
860  * This public SLOT is used for moving to minimal View Mode
861  *
862  * If b_minimal is false, then we are normalView
863  */
864 void MainInterface::toggleMinimalView( bool b_minimal )
865 {
866     if( !b_minimalView && b_autoresize ) /* Normal mode */
867     {
868         if( stackCentralW->currentWidget() == bgWidget )
869         {
870             if( stackCentralW->height() < 16 )
871             {
872                 resizeStack( stackCentralW->width(), 100 );
873             }
874         }
875     }
876     b_minimalView = b_minimal;
877     if( !b_videoFullScreen )
878     {
879         setMinimalView( b_minimalView );
880         computeMinimumSize();
881     }
882
883     emit minimalViewToggled( b_minimalView );
884 }
885
886 /* toggling advanced controls buttons */
887 void MainInterface::toggleAdvancedButtons()
888 {
889     controls->toggleAdvanced();
890 //    if( fullscreenControls ) fullscreenControls->toggleAdvanced();
891 }
892
893 /* Get the visibility status of the controls (hidden or not, advanced or not) */
894 int MainInterface::getControlsVisibilityStatus()
895 {
896     if( !controls ) return 0;
897     return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
898                 + CONTROLS_ADVANCED * controls->b_advancedVisible );
899 }
900
901 void MainInterface::setStatusBarVisibility( bool b_visible )
902 {
903     statusBar()->setVisible( b_visible );
904     b_statusbarVisible = b_visible;
905     if( controls ) controls->setGripVisible( !b_statusbarVisible );
906 }
907
908 #if 0
909 void MainInterface::visual()
910 {
911     if( !VISIBLE( visualSelector) )
912     {
913         visualSelector->show();
914         if( !THEMIM->getIM()->hasVideo() )
915         {
916             /* Show the background widget */
917         }
918         visualSelectorEnabled = true;
919     }
920     else
921     {
922         /* Stop any currently running visualization */
923         visualSelector->hide();
924         visualSelectorEnabled = false;
925     }
926 }
927 #endif
928
929 /************************************************************************
930  * Other stuff
931  ************************************************************************/
932 void MainInterface::setName( const QString& name )
933 {
934     input_name = name; /* store it for the QSystray use */
935     /* Display it in the status bar, but also as a Tooltip in case it doesn't
936        fit in the label */
937     nameLabel->setText( name );
938     nameLabel->setToolTip( name );
939 }
940
941 /**
942  * Give the decorations of the Main Window a correct Name.
943  * If nothing is given, set it to VLC...
944  **/
945 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
946 {
947     if( aTitle.isEmpty() )
948     {
949         setWindowTitle( qtr( "VLC media player" ) );
950     }
951     else
952     {
953         setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
954     }
955 }
956
957 void MainInterface::showCryptedLabel( bool b_show )
958 {
959     if( cryptedLabel == NULL )
960     {
961         cryptedLabel = new QLabel;
962         // The lock icon is not the right one for DRM protection/scrambled.
963         //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
964         cryptedLabel->setText( "DRM" );
965         statusBar()->addWidget( cryptedLabel );
966     }
967
968     cryptedLabel->setVisible( b_show );
969 }
970
971 void MainInterface::showBuffering( float f_cache )
972 {
973     QString amount = QString("Buffering: %1%").arg( (int)(100*f_cache) );
974     statusBar()->showMessage( amount, 1000 );
975 }
976
977 /*****************************************************************************
978  * Systray Icon and Systray Menu
979  *****************************************************************************/
980 /**
981  * Create a SystemTray icon and a menu that would go with it.
982  * Connects to a click handler on the icon.
983  **/
984 void MainInterface::createSystray()
985 {
986     QIcon iconVLC;
987     if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
988         iconVLC =  QIcon( ":/logo/vlc128-xmas.png" );
989     else
990         iconVLC =  QIcon( ":/logo/vlc128.png" );
991     sysTray = new QSystemTrayIcon( iconVLC, this );
992     sysTray->setToolTip( qtr( "VLC media player" ));
993
994     systrayMenu = new QMenu( qtr( "VLC media player" ), this );
995     systrayMenu->setIcon( iconVLC );
996
997     QVLCMenu::updateSystrayMenu( this, p_intf, true );
998     sysTray->show();
999
1000     CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
1001              this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
1002
1003     /* Connects on nameChanged() */
1004     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
1005              this, updateSystrayTooltipName( const QString& ) );
1006     /* Connect PLAY_STATUS on the systray */
1007     CONNECT( THEMIM->getIM(), playingStatusChanged( int ),
1008              this, updateSystrayTooltipStatus( int ) );
1009 }
1010
1011 /**
1012  * Updates the Systray Icon's menu and toggle the main interface
1013  */
1014 void MainInterface::toggleUpdateSystrayMenu()
1015 {
1016     /* If hidden, show it */
1017     if( isHidden() )
1018     {
1019         show();
1020         activateWindow();
1021     }
1022     else if( isMinimized() )
1023     {
1024         /* Minimized */
1025         showNormal();
1026         activateWindow();
1027     }
1028     else
1029     {
1030         /* Visible (possibly under other windows) */
1031 #ifdef WIN32
1032         /* check if any visible window is above vlc in the z-order,
1033          * but ignore the ones always on top
1034          * and the ones which can't be activated */
1035         WINDOWINFO wi;
1036         HWND hwnd;
1037         wi.cbSize = sizeof( WINDOWINFO );
1038         for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
1039                 hwnd && ( !IsWindowVisible( hwnd ) ||
1040                     ( GetWindowInfo( hwnd, &wi ) &&
1041                       (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
1042                 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
1043             if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
1044                 (wi.dwExStyle&WS_EX_TOPMOST) )
1045             {
1046                 hide();
1047             }
1048             else
1049             {
1050                 activateWindow();
1051             }
1052 #else
1053         hide();
1054 #endif
1055     }
1056     if( sysTray )
1057         QVLCMenu::updateSystrayMenu( this, p_intf );
1058 }
1059
1060 /* First Item of the systray menu */
1061 void MainInterface::showUpdateSystrayMenu()
1062 {
1063     if( isHidden() )
1064         show();
1065     if( isMinimized() )
1066         showNormal();
1067     activateWindow();
1068
1069     QVLCMenu::updateSystrayMenu( this, p_intf );
1070 }
1071
1072 /* First Item of the systray menu */
1073 void MainInterface::hideUpdateSystrayMenu()
1074 {
1075     hide();
1076     QVLCMenu::updateSystrayMenu( this, p_intf );
1077 }
1078
1079 /* Click on systray Icon */
1080 void MainInterface::handleSystrayClick(
1081                                     QSystemTrayIcon::ActivationReason reason )
1082 {
1083     switch( reason )
1084     {
1085         case QSystemTrayIcon::Trigger:
1086         case QSystemTrayIcon::DoubleClick:
1087 #ifdef Q_WS_MAC
1088             QVLCMenu::updateSystrayMenu( this, p_intf );
1089 #else
1090             toggleUpdateSystrayMenu();
1091 #endif
1092             break;
1093         case QSystemTrayIcon::MiddleClick:
1094             sysTray->showMessage( qtr( "VLC media player" ),
1095                     qtr( "Control menu for the player" ),
1096                     QSystemTrayIcon::Information, 3000 );
1097             break;
1098         default:
1099             break;
1100     }
1101 }
1102
1103 /**
1104  * Updates the name of the systray Icon tooltip.
1105  * Doesn't check if the systray exists, check before you call it.
1106  **/
1107 void MainInterface::updateSystrayTooltipName( const QString& name )
1108 {
1109     if( name.isEmpty() )
1110     {
1111         sysTray->setToolTip( qtr( "VLC media player" ) );
1112     }
1113     else
1114     {
1115         sysTray->setToolTip( name );
1116         if( b_notificationEnabled && ( isHidden() || isMinimized() ) )
1117         {
1118             sysTray->showMessage( qtr( "VLC media player" ), name,
1119                     QSystemTrayIcon::NoIcon, 3000 );
1120         }
1121     }
1122
1123     QVLCMenu::updateSystrayMenu( this, p_intf );
1124 }
1125
1126 /**
1127  * Updates the status of the systray Icon tooltip.
1128  * Doesn't check if the systray exists, check before you call it.
1129  **/
1130 void MainInterface::updateSystrayTooltipStatus( int i_status )
1131 {
1132     switch( i_status )
1133     {
1134     case PLAYING_S:
1135         sysTray->setToolTip( input_name );
1136         break;
1137     case PAUSE_S:
1138         sysTray->setToolTip( input_name + " - " + qtr( "Paused") );
1139         break;
1140     default:
1141         sysTray->setToolTip( qtr( "VLC media player" ) );
1142         break;
1143     }
1144     QVLCMenu::updateSystrayMenu( this, p_intf );
1145 }
1146
1147 void MainInterface::changeEvent(QEvent *event)
1148 {
1149     if( event->type() == QEvent::WindowStateChange )
1150     {
1151         QWindowStateChangeEvent *windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
1152         Qt::WindowStates newState = windowState();
1153         Qt::WindowStates oldState = windowStateChangeEvent->oldState();
1154
1155         if( newState & Qt::WindowMinimized )
1156         {
1157             b_hasPausedWhenMinimized = false;
1158
1159             if( THEMIM->getIM()->playingStatus() == PLAYING_S &&
1160                 THEMIM->getIM()->hasVideo() && !THEMIM->getIM()->hasVisualisation() &&
1161                 b_pauseOnMinimize )
1162             {
1163                 b_hasPausedWhenMinimized = true;
1164                 THEMIM->pause();
1165             }
1166         }
1167         else if( oldState & Qt::WindowMinimized && !( newState & Qt::WindowMinimized ) )
1168         {
1169             if( b_hasPausedWhenMinimized )
1170             {
1171                 THEMIM->play();
1172             }
1173         }
1174     }
1175
1176     QWidget::changeEvent(event);
1177 }
1178
1179 /************************************************************************
1180  * D&D Events
1181  ************************************************************************/
1182 void MainInterface::dropEvent(QDropEvent *event)
1183 {
1184     dropEventPlay( event, true );
1185 }
1186
1187 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1188 {
1189     if( event->possibleActions() & Qt::CopyAction )
1190        event->setDropAction( Qt::CopyAction );
1191     else
1192         return;
1193
1194     const QMimeData *mimeData = event->mimeData();
1195
1196     /* D&D of a subtitles file, add it on the fly */
1197     if( mimeData->urls().count() == 1 && THEMIM->getIM()->hasInput() )
1198     {
1199         if( !input_AddSubtitle( THEMIM->getInput(),
1200                  qtu( toNativeSeparators( mimeData->urls()[0].toLocalFile() ) ),
1201                  true ) )
1202         {
1203             event->accept();
1204             return;
1205         }
1206     }
1207
1208     bool first = b_play;
1209     foreach( const QUrl &url, mimeData->urls() )
1210     {
1211         if( url.isValid() )
1212         {
1213             QString mrl = toURI( url.toEncoded().constData() );
1214             playlist_Add( THEPL, qtu(mrl), NULL,
1215                           PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1216                           PLAYLIST_END, true, pl_Unlocked );
1217             first = false;
1218             RecentsMRL::getInstance( p_intf )->addRecent( url.toString() );
1219         }
1220     }
1221
1222     /* Browsers give content as text if you dnd the addressbar,
1223        so check if mimedata has valid url in text and use it
1224        if we didn't get any normal Urls()*/
1225     if( !mimeData->hasUrls() && mimeData->hasText() &&
1226         QUrl(mimeData->text()).isValid() )
1227     {
1228         QString mrl = toURI( mimeData->text() );
1229         playlist_Add( THEPL, qtu(mrl), NULL,
1230                       PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1231                       PLAYLIST_END, true, pl_Unlocked );
1232     }
1233     event->accept();
1234 }
1235 void MainInterface::dragEnterEvent(QDragEnterEvent *event)
1236 {
1237      event->acceptProposedAction();
1238 }
1239 void MainInterface::dragMoveEvent(QDragMoveEvent *event)
1240 {
1241      event->acceptProposedAction();
1242 }
1243 void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
1244 {
1245      event->accept();
1246 }
1247
1248 /************************************************************************
1249  * Events stuff
1250  ************************************************************************/
1251 void MainInterface::keyPressEvent( QKeyEvent *e )
1252 {
1253     handleKeyPress( e );
1254 }
1255
1256 void MainInterface::handleKeyPress( QKeyEvent *e )
1257 {
1258     if( ( e->modifiers() &  Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) )
1259     {
1260         toggleMinimalView( !b_minimalView );
1261         e->accept();
1262     }
1263
1264     int i_vlck = qtEventToVLCKey( e );
1265     if( i_vlck > 0 )
1266     {
1267         var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1268         e->accept();
1269     }
1270     else
1271         e->ignore();
1272 }
1273
1274 void MainInterface::wheelEvent( QWheelEvent *e )
1275 {
1276     int i_vlckey = qtWheelEventToVLCKey( e );
1277     var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1278     e->accept();
1279 }
1280
1281 void MainInterface::closeEvent( QCloseEvent *e )
1282 {
1283 //  hide();
1284     emit askToQuit(); /* ask THEDP to quit, so we have a unique method */
1285     /* Accept session quit. Otherwise we break the desktop mamager. */
1286     e->accept();
1287 }
1288
1289 void MainInterface::setInterfaceFullScreen( bool fs )
1290 {
1291     if( fs )
1292         setWindowState( windowState() | Qt::WindowFullScreen );
1293     else
1294         setWindowState( windowState() & ~Qt::WindowFullScreen );
1295 }
1296 void MainInterface::toggleInterfaceFullScreen()
1297 {
1298     b_interfaceFullScreen = !b_interfaceFullScreen;
1299     if( !b_videoFullScreen )
1300         setInterfaceFullScreen( b_interfaceFullScreen );
1301     emit fullscreenInterfaceToggled( b_interfaceFullScreen );
1302 }
1303
1304 void MainInterface::emitBoss()
1305 {
1306     emit askBoss();
1307 }
1308 void MainInterface::setBoss()
1309 {
1310     THEMIM->pause();
1311     if( sysTray )
1312     {
1313         hide();
1314     }
1315     else
1316     {
1317         showMinimized();
1318     }
1319 }
1320
1321 void MainInterface::emitRaise()
1322 {
1323     emit askRaise();
1324 }
1325 void MainInterface::setRaise()
1326 {
1327     activateWindow();
1328     raise();
1329 }
1330
1331 /*****************************************************************************
1332  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1333  *  We don't show the menu directly here because we don't want the
1334  *  caller to block for a too long time.
1335  *****************************************************************************/
1336 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1337                         vlc_value_t old_val, vlc_value_t new_val, void *param )
1338 {
1339     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1340
1341     intf_thread_t *p_intf = (intf_thread_t *)param;
1342
1343     if( p_intf->pf_show_dialog )
1344     {
1345         p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1346                                 new_val.b_bool, NULL );
1347     }
1348
1349     return VLC_SUCCESS;
1350 }
1351
1352 /*****************************************************************************
1353  * IntfShowCB: callback triggered by the intf-toggle-fscontrol libvlc variable.
1354  *****************************************************************************/
1355 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1356                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1357 {
1358     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1359     VLC_UNUSED( new_val );
1360
1361     intf_thread_t *p_intf = (intf_thread_t *)param;
1362     p_intf->p_sys->p_mi->toggleFSC();
1363
1364     /* Show event */
1365      return VLC_SUCCESS;
1366 }
1367
1368 /*****************************************************************************
1369  * IntfRaiseMainCB: callback triggered by the intf-show-main libvlc variable.
1370  *****************************************************************************/
1371 static int IntfRaiseMainCB( vlc_object_t *p_this, const char *psz_variable,
1372                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1373 {
1374     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1375     VLC_UNUSED( new_val );
1376
1377     intf_thread_t *p_intf = (intf_thread_t *)param;
1378     p_intf->p_sys->p_mi->emitRaise();
1379
1380     return VLC_SUCCESS;
1381 }
1382
1383 /*****************************************************************************
1384  * IntfBossCB: callback triggered by the intf-boss libvlc variable.
1385  *****************************************************************************/
1386 static int IntfBossCB( vlc_object_t *p_this, const char *psz_variable,
1387                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1388 {
1389     VLC_UNUSED( p_this ); VLC_UNUSED( psz_variable ); VLC_UNUSED( old_val );
1390     VLC_UNUSED( new_val );
1391
1392     intf_thread_t *p_intf = (intf_thread_t *)param;
1393     p_intf->p_sys->p_mi->emitBoss();
1394
1395     return VLC_SUCCESS;
1396 }