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