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