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