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