]> git.sesse.net Git - vlc/blob - modules/gui/qt4/main_interface.cpp
Added window roles for X11
[vlc] / modules / gui / qt4 / main_interface.cpp
1 /*****************************************************************************
2  * main_interface.cpp : Main interface
3  ****************************************************************************
4  * Copyright (C) 2006-2009 the VideoLAN team
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
23  * Foundation, Inc., 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"
34 #include "actions_manager.hpp"
35
36 #include "util/customwidgets.hpp"
37 #include "util/qt_dirs.hpp"
38
39 #include "components/interface_widgets.hpp"
40 #include "components/controller.hpp"
41 #include "components/playlist/playlist.hpp"
42 #include "dialogs/external.hpp"
43
44 #include "menus.hpp"
45 #include "recents.hpp"
46
47 #include <QCloseEvent>
48 #include <QKeyEvent>
49
50 #include <QUrl>
51 #include <QSize>
52 #include <QDate>
53
54 #include <QMenu>
55 #include <QMenuBar>
56 #include <QStatusBar>
57 #include <QLabel>
58 #include <QGroupBox>
59 #include <QPushButton>
60
61 #ifdef WIN32
62  #include <vlc_windows_interfaces.h>
63  #include <QBitmap>
64 #endif
65
66 #include <assert.h>
67
68 #include <vlc_keys.h> /* Wheel event */
69 #include <vlc_vout_window.h>
70 #include <vlc_vout.h>
71
72 /* Callback prototypes */
73 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
74                         vlc_value_t old_val, vlc_value_t new_val, void *param );
75 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
76                        vlc_value_t old_val, vlc_value_t new_val, void *param );
77
78 MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
79 {
80     /* Variables initialisation */
81     // need_components_update = false;
82     bgWidget             = NULL;
83     videoWidget          = NULL;
84     playlistWidget       = NULL;
85     sysTray              = NULL;
86     videoIsActive        = false;
87     playlistVisible      = false;
88     input_name           = "";
89     fullscreenControls   = NULL;
90     cryptedLabel         = NULL;
91     controls             = NULL;
92     inputC               = NULL;
93     b_shouldHide         = false;
94
95     bgWasVisible         = false;
96     i_bg_height          = 0;
97
98     /* Ask for privacy */
99     askForPrivacy();
100
101     /**
102      *  Configuration and settings
103      *  Pre-building of interface
104      **/
105     /* Main settings */
106     setFocusPolicy( Qt::StrongFocus );
107     setAcceptDrops( true );
108     setWindowRole( "vlc-main" );
109     setWindowIcon( QApplication::windowIcon() );
110     setWindowOpacity( config_GetFloat( p_intf, "qt-opacity" ) );
111
112     /* Set The Video In emebedded Mode or not */
113     videoEmbeddedFlag = config_GetInt( p_intf, "embedded-video" );
114
115     /* Does the interface resize to video size or the opposite */
116     b_keep_size = !config_GetInt( p_intf, "qt-video-autoresize" );
117
118     /* Are we in the enhanced always-video mode or not ? */
119     i_visualmode = config_GetInt( p_intf, "qt-display-mode" );
120
121     /* Set the other interface settings */
122     settings = getSettings();
123     settings->beginGroup( "MainWindow" );
124
125     /**
126      * Retrieve saved sizes for main window
127      *   mainBasedSize = based window size for normal mode
128      *                  (no video, no background)
129      *   mainVideoSize = window size with video (all modes)
130      **/
131     mainBasedSize = settings->value( "mainBasedSize", QSize( 350, 120 ) ).toSize();
132     mainVideoSize = settings->value( "mainVideoSize", QSize( 400, 300 ) ).toSize();
133
134     /* Do we want anoying popups or not */
135     notificationEnabled = (bool)config_GetInt( p_intf, "qt-notification" );
136
137     /**************
138      * Status Bar *
139      **************/
140     createStatusBar();
141
142     /**************************
143      *  UI and Widgets design
144      **************************/
145     setVLCWindowsTitle();
146     createMainWidget( settings );
147
148     /************
149      * Menu Bar *
150      ************/
151     QVLCMenu::createMenuBar( this, p_intf );
152     CONNECT( THEMIM->getIM(), voutListChanged( vout_thread_t **, int ),
153              this, destroyPopupMenu() );
154
155 #if 0
156     /* Create a Dock to get the playlist */
157     dockPL = new QDockWidget( qtr( "Playlist" ), this );
158     dockPL->setSizePolicy( QSizePolicy::Preferred,
159                            QSizePolicy::Expanding );
160     dockPL->setFeatures( QDockWidget::AllDockWidgetFeatures );
161     dockPL->setAllowedAreas( Qt::LeftDockWidgetArea
162                            | Qt::RightDockWidgetArea
163                            | Qt::BottomDockWidgetArea );
164     dockPL->hide();
165 #endif
166
167     /********************
168      * Input Manager    *
169      ********************/
170     MainInputManager::getInstance( p_intf );
171
172     /*********************************
173      * Create the Systray Management *
174      *********************************/
175     initSystray();
176
177     /**************************
178      * Various CONNECTs on IM *
179      **************************/
180     /* Connect the input manager to the GUI elements it manages */
181
182     /**
183      * Connects on nameChanged()
184      * Those connects are not merged because different options can trigger
185      * them down.
186      */
187     /* Naming in the controller statusbar */
188     CONNECT( THEMIM->getIM(), nameChanged( const QString& ),
189              this, setName( const QString& ) );
190     /* and in the systray */
191     if( sysTray )
192     {
193         CONNECT( THEMIM->getIM(), nameChanged( const QString& ), this,
194                  updateSystrayTooltipName( const QString& ) );
195     }
196     /* and in the title of the controller */
197     if( config_GetInt( p_intf, "qt-name-in-title" ) )
198     {
199         CONNECT( THEMIM->getIM(), nameChanged( const QString& ), this,
200              setVLCWindowsTitle( const QString& ) );
201     }
202
203     /**
204      * CONNECTS on PLAY_STATUS
205      **/
206     /* Status on the systray */
207     if( sysTray )
208     {
209         CONNECT( THEMIM->getIM(), statusChanged( int ),
210                  this, updateSystrayTooltipStatus( int ) );
211     }
212
213
214     /* END CONNECTS ON IM */
215
216     /************
217      * Callbacks
218      ************/
219     var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
220
221     /* Register callback for the intf-popupmenu variable */
222     var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
223
224
225     /* VideoWidget connects for asynchronous calls */
226     connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
227              this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
228              Qt::BlockingQueuedConnection );
229     connect( this, SIGNAL(askReleaseVideo( void )),
230              this, SLOT(releaseVideoSlot( void )),
231              Qt::BlockingQueuedConnection );
232
233     if( videoWidget )
234     {
235         CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
236                  videoWidget, SetSizing( unsigned int, unsigned int ) );
237         CONNECT( this, askVideoSetFullScreen( bool ),
238                  videoWidget, SetFullScreen( bool ) );
239         CONNECT( videoWidget, keyPressed( QKeyEvent * ),
240                  this, handleKeyPress( QKeyEvent * ) );
241     }
242
243     CONNECT( this, askUpdate(), this, doComponentsUpdate() );
244     CONNECT( THEDP, toolBarConfUpdated(), this, recreateToolbars() );
245
246     /* Size and placement of interface */
247     settings->beginGroup( "MainWindow" );
248     QVLCTools::restoreWidgetPosition( settings, this, QSize(380, 60) );
249
250     /* resize to previously saved main window size if appicable */
251     if( b_keep_size )
252     {
253        if( i_visualmode == QT_ALWAYS_VIDEO_MODE ||
254            i_visualmode == QT_MINIMAL_MODE )
255        {
256            resize( mainVideoSize );
257        }
258        else
259        {
260            resize( mainBasedSize );
261        }
262     }
263
264     bool b_visible = settings->value( "playlist-visible", 0 ).toInt();
265     settings->endGroup();
266
267     /* Playlist */
268     if( b_visible ) togglePlaylist();
269
270     /* Enable the popup menu in the MI */
271     setContextMenuPolicy( Qt::CustomContextMenu );
272     CONNECT( this, customContextMenuRequested( const QPoint& ),
273              this, popupMenu( const QPoint& ) );
274
275     /* Final sizing and showing */
276     setMinimumWidth( __MAX( controls->sizeHint().width(),
277                             menuBar()->sizeHint().width() ) );
278     setVisible( !b_shouldHide );
279
280     /* And switch to minimal view if needed
281        Must be called after the show() */
282     if( i_visualmode == QT_MINIMAL_MODE )
283         toggleMinimalView( true );
284
285     /* Update the geometry : It is useful if you switch between
286        qt-display-modes ?*/
287     updateGeometry();
288     resize( sizeHint() );
289
290 #ifdef WIN32
291     /*Here is the code for the taskbar thumb buttons
292     FIXME:We need pretty buttons in 16x16 px that are handled correctly by masks in Qt
293     FIXME:the play button's picture doesn't changed to pause when clicked
294     */
295     OSVERSIONINFO winVer;
296     winVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
297     if( GetVersionEx(&winVer) && winVer.dwMajorVersion > 5 && winVer.dwMajorVersion > 0 )
298     {
299         if(himl = ImageList_Create( 15, //cx
300                                     18, //cy
301                                     ILC_COLOR,//flags
302                                     4,//initial nb of images
303                                     0//nb of images that can be added
304                                     ))
305         {
306             QPixmap img   = QPixmap(":/toolbar/previous_b");
307             QPixmap img2  = QPixmap(":/toolbar/pause_b");
308             QPixmap img3  = QPixmap(":/toolbar/play_b");
309             QPixmap img4  = QPixmap(":/toolbar/next_b");
310             QBitmap mask  = img.createMaskFromColor(Qt::transparent);
311             QBitmap mask2 = img2.createMaskFromColor(Qt::transparent);
312             QBitmap mask3 = img3.createMaskFromColor(Qt::transparent);
313             QBitmap mask4 = img4.createMaskFromColor(Qt::transparent);
314
315             if(-1 == ImageList_Add(himl, img.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask.toWinHBITMAP()))
316                 msg_Err( p_intf, "ImageList_Add failed" );
317             if(-1 == ImageList_Add(himl, img2.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask2.toWinHBITMAP()))
318                 msg_Err( p_intf, "ImageList_Add failed" );
319             if(-1 == ImageList_Add(himl, img3.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask3.toWinHBITMAP()))
320                 msg_Err( p_intf, "ImageList_Add failed" );
321             if(-1 == ImageList_Add(himl, img4.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask4.toWinHBITMAP()))
322                 msg_Err( p_intf, "ImageList_Add failed" );
323         }
324
325         CoInitialize( 0 );
326
327         if( S_OK == CoCreateInstance( &clsid_ITaskbarList,
328                     NULL, CLSCTX_INPROC_SERVER,
329                     &IID_ITaskbarList3,
330                     (void **)&p_taskbl) )
331         {
332             p_taskbl->vt->HrInit(p_taskbl);
333
334             int msg_value = RegisterWindowMessage("TaskbarButtonCreated");
335             //msg_Info( p_intf, "msg value: %04x", msg_value );
336
337             // Define an array of two buttons. These buttons provide images through an 
338             // image list and also provide tooltips.
339             DWORD dwMask = THB_BITMAP | THB_FLAGS;
340
341             THUMBBUTTON thbButtons[2];
342             thbButtons[0].dwMask = dwMask;
343             thbButtons[0].iId = 0;
344             thbButtons[0].iBitmap = 0;
345             thbButtons[0].dwFlags = THBF_HIDDEN;
346
347             thbButtons[1].dwMask = dwMask;
348             thbButtons[1].iId = 1;
349             thbButtons[1].iBitmap = 2;
350             thbButtons[1].dwFlags = THBF_HIDDEN;
351
352             thbButtons[2].dwMask = dwMask;
353             thbButtons[2].iId = 2;
354             thbButtons[2].iBitmap = 3;
355             thbButtons[2].dwFlags = THBF_HIDDEN;
356
357             HRESULT hr = p_taskbl->vt->ThumbBarSetImageList(p_taskbl, GetForegroundWindow(), himl );
358             if(S_OK != hr)
359                 msg_Err( p_intf, "ThumbBarSetImageList failed with error %08x", hr );
360             if(S_OK != p_taskbl->vt->ThumbBarAddButtons(p_taskbl, GetForegroundWindow(), 3, thbButtons))
361                 msg_Err( p_intf, "ThumbBarAddButtons failed with error %08x", GetLastError() );
362
363         }
364         CONNECT( THEMIM->getIM(), statusChanged( int ), this, changeThumbbarButtons( int ) );
365     }
366     else
367     {
368         himl = NULL;
369         p_taskbl = NULL;
370     }
371 #endif
372
373 }
374
375 MainInterface::~MainInterface()
376 {
377     msg_Dbg( p_intf, "Destroying the main interface" );
378
379     /* Unsure we hide the videoWidget before destroying it */
380     if( videoIsActive ) videoWidget->hide();
381
382     /* Save playlist state */
383     if( playlistWidget )
384     {
385         if( !isDocked() )
386             QVLCTools::saveWidgetPosition( p_intf, "Playlist", playlistWidget );
387
388         delete playlistWidget;
389     }
390
391 #ifdef WIN32
392     if( himl )
393         ImageList_Destroy( himl );
394     if(p_taskbl)
395         p_taskbl->vt->Release(p_taskbl);
396     CoUninitialize();
397 #endif
398
399     /* Be sure to kill the actionsManager... FIXME */
400     ActionsManager::killInstance();
401
402     /* Delete the FSC controller */
403     delete fullscreenControls;
404
405     /* Save states */
406     settings->beginGroup( "MainWindow" );
407     settings->setValue( "pl-dock-status", (int)i_pl_dock );
408     settings->setValue( "playlist-visible", (int)playlistVisible );
409     settings->setValue( "adv-controls",
410                         getControlsVisibilityStatus() & CONTROLS_ADVANCED );
411
412     settings->setValue( "mainBasedSize", mainBasedSize );
413     settings->setValue( "mainVideoSize", mainVideoSize );
414
415     if( bgWidget )
416         settings->setValue( "backgroundSize", bgWidget->size() );
417
418     /* Save this size */
419     QVLCTools::saveWidgetPosition(settings, this);
420     settings->endGroup();
421
422
423     /* Unregister callbacks */
424     var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );
425     var_DelCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
426
427     p_intf->p_sys->p_mi = NULL;
428 }
429
430 /*****************************
431  *   Main UI handling        *
432  *****************************/
433 void MainInterface::recreateToolbars()
434 {
435     msg_Dbg( p_intf, "Recreating the toolbars" );
436     settings->beginGroup( "MainWindow" );
437     delete controls;
438     delete inputC;
439     controls = new ControlsWidget( p_intf, false, this ); /* FIXME */
440     CONNECT( controls, advancedControlsToggled( bool ),
441              this, doComponentsUpdate() );
442     CONNECT( controls, sizeChanged(),
443              this, doComponentsUpdate() );
444     inputC = new InputControlsWidget( p_intf, this );
445
446     mainLayout->addWidget( inputC, 2, 0, 1, -1, Qt::AlignBottom );
447     mainLayout->addWidget( controls, settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
448                               0, 1, -1, Qt::AlignBottom );
449     settings->endGroup();
450 }
451
452 void MainInterface::createMainWidget( QSettings *settings )
453 {
454     /* Create the main Widget and the mainLayout */
455     QWidget *main = new QWidget;
456     setCentralWidget( main );
457     mainLayout = new QGridLayout( main );
458
459     /* Margins, spacing */
460     main->setContentsMargins( 0, 0, 0, 0 );
461     main->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
462     mainLayout->setSpacing( 0 );
463     mainLayout->setMargin( 0 );
464
465     /* Visualisation */
466     /* Disabled for now, they SUCK */
467     #if 0
468     visualSelector = new VisualSelector( p_intf );
469     mainLayout->insertWidget( 0, visualSelector );
470     visualSelector->hide();
471     #endif
472
473     /* Bg Cone */
474     bgWidget = new BackgroundWidget( p_intf );
475     bgWidget->resize(
476             settings->value( "backgroundSize", QSize( 300, 200 ) ).toSize() );
477     bgWidget->updateGeometry();
478
479     if( i_visualmode != QT_ALWAYS_VIDEO_MODE &&
480         i_visualmode != QT_MINIMAL_MODE )
481     {
482         bgWidget->hide();
483     }
484
485     /* And video Outputs */
486     if( videoEmbeddedFlag )
487         videoWidget = new VideoWidget( p_intf );
488
489     /* Create the CONTROLS Widget */
490     controls = new ControlsWidget( p_intf,
491                    settings->value( "adv-controls", false ).toBool(), this );
492     CONNECT( controls, advancedControlsToggled( bool ),
493              this, doComponentsUpdate() );
494     CONNECT( controls, sizeChanged(),
495              this, doComponentsUpdate() );
496     inputC = new InputControlsWidget( p_intf, this );
497
498
499     /* Add the controls Widget to the main Widget */
500     if( videoWidget ){
501         mainLayout->addWidget( videoWidget, 0, 0, 1, -1 );
502         mainLayout->setRowStretch( 0, 10 );
503     }
504     mainLayout->addWidget( bgWidget, 1, 0, 1, -1 );
505     //mainLayout->setRowStretch( 1, 10 );
506     mainLayout->addWidget( inputC, 2, 0, 1, -1, Qt::AlignBottom );
507     mainLayout->addWidget( controls, settings->value( "ToolbarPos", 0 ).toInt() ? 0: 3,
508                            0, 1, -1, Qt::AlignBottom );
509
510     /* Finish the sizing */
511     main->updateGeometry();
512
513     getSettings()->endGroup();
514 #ifdef WIN32
515     if ( depth() > 8 )
516 #endif
517     /* Create the FULLSCREEN CONTROLS Widget */
518     if( config_GetInt( p_intf, "qt-fs-controller" ) )
519     {
520         fullscreenControls = new FullscreenControllerWidget( p_intf, this );
521         CONNECT( fullscreenControls, keyPressed( QKeyEvent * ),
522                  this, handleKeyPress( QKeyEvent * ) );
523     }
524 }
525
526 inline void MainInterface::createStatusBar()
527 {
528     /****************
529      *  Status Bar  *
530      ****************/
531     /* Widgets Creation*/
532     QStatusBar *statusBarr = statusBar();
533
534     TimeLabel *timeLabel = new TimeLabel( p_intf );
535     nameLabel = new QLabel( this );
536     nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
537                                       | Qt::TextSelectableByKeyboard );
538     SpeedLabel *speedLabel = new SpeedLabel( p_intf, "1.00x", this );
539
540     /* Styling those labels */
541     timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
542     speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
543     nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);
544
545     /* and adding those */
546     statusBarr->addWidget( nameLabel, 8 );
547     statusBarr->addPermanentWidget( speedLabel, 0 );
548     statusBarr->addPermanentWidget( timeLabel, 0 );
549
550     /* timeLabel behaviour:
551        - double clicking opens the goto time dialog
552        - right-clicking and clicking just toggle between remaining and
553          elapsed time.*/
554     CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
555
556     CONNECT( THEMIM->getIM(), encryptionChanged( bool ),
557              this, showCryptedLabel( bool ) );
558 }
559
560 inline void MainInterface::initSystray()
561 {
562     bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
563     bool b_systrayWanted = config_GetInt( p_intf, "qt-system-tray" );
564
565     if( config_GetInt( p_intf, "qt-start-minimized") > 0 )
566     {
567         if( b_systrayAvailable )
568         {
569             b_systrayWanted = true;
570             b_shouldHide = true;
571         }
572         else
573             msg_Err( p_intf, "cannot start minimized without system tray bar" );
574     }
575
576     if( b_systrayAvailable && b_systrayWanted )
577             createSystray();
578 }
579
580 inline void MainInterface::askForPrivacy()
581 {
582     /**
583      * Ask for the network policy on FIRST STARTUP
584      **/
585     if( config_GetInt( p_intf, "qt-privacy-ask") )
586     {
587         QList<ConfigControl *> controls;
588         if( privacyDialog( &controls ) == QDialog::Accepted )
589         {
590             QList<ConfigControl *>::Iterator i;
591             for(  i = controls.begin() ; i != controls.end() ; i++ )
592             {
593                 ConfigControl *c = qobject_cast<ConfigControl *>(*i);
594                 c->doApply( p_intf );
595             }
596
597             config_PutInt( p_intf,  "qt-privacy-ask" , 0 );
598             /* We have to save here because the user may not launch Prefs */
599             config_SaveConfigFile( p_intf, NULL );
600         }
601     }
602 }
603
604 int MainInterface::privacyDialog( QList<ConfigControl *> *controls )
605 {
606     QDialog *privacy = new QDialog( this );
607
608     privacy->setWindowTitle( qtr( "Privacy and Network Policies" ) );
609     privacy->setWindowRole( "vlc-privacy" );
610
611     QGridLayout *gLayout = new QGridLayout( privacy );
612
613     QGroupBox *blabla = new QGroupBox( qtr( "Privacy and Network Warning" ) );
614     QGridLayout *blablaLayout = new QGridLayout( blabla );
615     QLabel *text = new QLabel( qtr(
616         "<p>The <i>VideoLAN Team</i> doesn't like when an application goes "
617         "online without authorization.</p>\n "
618         "<p><i>VLC media player</i> can retreive limited information from "
619         "the Internet in order to get CD covers or to check "
620         "for available updates.</p>\n"
621         "<p><i>VLC media player</i> <b>DOES NOT</b> send or collect <b>ANY</b> "
622         "information, even anonymously, about your usage.</p>\n"
623         "<p>Therefore please select from the following options, the default being "
624         "almost no access to the web.</p>\n") );
625     text->setWordWrap( true );
626     text->setTextFormat( Qt::RichText );
627
628     blablaLayout->addWidget( text, 0, 0 ) ;
629
630     QGroupBox *options = new QGroupBox;
631     QGridLayout *optionsLayout = new QGridLayout( options );
632
633     gLayout->addWidget( blabla, 0, 0, 1, 3 );
634     gLayout->addWidget( options, 1, 0, 1, 3 );
635     module_config_t *p_config;
636     ConfigControl *control;
637     int line = 0;
638
639 #define CONFIG_GENERIC( option, type )                            \
640     p_config =  config_FindConfig( VLC_OBJECT(p_intf), option );  \
641     if( p_config )                                                \
642     {                                                             \
643         control =  new type ## ConfigControl( VLC_OBJECT(p_intf), \
644                 p_config, options, false, optionsLayout, line );  \
645         controls->append( control );                               \
646     }
647
648 #define CONFIG_GENERIC_NOBOOL( option, type )                     \
649     p_config =  config_FindConfig( VLC_OBJECT(p_intf), option );  \
650     if( p_config )                                                \
651     {                                                             \
652         control =  new type ## ConfigControl( VLC_OBJECT(p_intf), \
653                 p_config, options, optionsLayout, line );  \
654         controls->append( control );                               \
655     }
656
657     CONFIG_GENERIC( "album-art", IntegerList ); line++;
658 #ifdef UPDATE_CHECK
659     CONFIG_GENERIC_NOBOOL( "qt-updates-notif", Bool ); line++;
660 #endif
661
662     QPushButton *ok = new QPushButton( qtr( "OK" ) );
663
664     gLayout->addWidget( ok, 2, 2 );
665
666     CONNECT( ok, clicked(), privacy, accept() );
667     return privacy->exec();
668 }
669
670
671 /**********************************************************************
672  * Handling of sizing of the components
673  **********************************************************************/
674
675 /* This function is probably wrong, but we don't have many many choices...
676    Since we can't know from the playlist Widget if we are inside a dock or not,
677    because the playlist Widget can be called by THEDP, as a separate windows for
678    the skins.
679    Maybe the other solution is to redefine the sizeHint() of the playlist and
680    ask _parent->isFloating()...
681    If you think this would be better, please FIXME it...
682 */
683
684 QSize MainInterface::sizeHint() const
685 {
686     if( b_keep_size )
687     {
688         if( i_visualmode == QT_ALWAYS_VIDEO_MODE ||
689             i_visualmode == QT_MINIMAL_MODE )
690         {
691                 return mainVideoSize;
692         }
693         else
694         {
695             if( VISIBLE( bgWidget) ||
696                 ( videoIsActive && videoWidget->isVisible() )
697               )
698                 return mainVideoSize;
699             else
700                 return mainBasedSize;
701         }
702     }
703
704     int nwidth  = controls->sizeHint().width();
705     int nheight = controls->isVisible() ?
706                   controls->size().height()
707                   + inputC->size().height()
708                   + menuBar()->size().height()
709                   + statusBar()->size().height()
710                   : 0 ;
711
712     if( VISIBLE( bgWidget ) )
713     {
714         if( i_bg_height )
715             nheight += i_bg_height;
716         else
717             nheight += bgWidget->size().height();
718         nwidth  = __MAX( nwidth, bgWidget->size().width() );
719     }
720     else if( videoIsActive && videoWidget->isVisible() )
721     {
722         nheight += videoWidget->sizeHint().height();
723         nwidth  = __MAX( nwidth, videoWidget->sizeHint().width() );
724     }
725 #if 0
726     if( !dockPL->isFloating() && dockPL->isVisible() && dockPL->widget()  )
727     {
728         nheight += dockPL->size().height();
729         nwidth = __MAX( nwidth, dockPL->size().width() );
730         msg_Warn( p_intf, "3 %i %i", nheight, nwidth );
731     }
732 #endif
733     return QSize( nwidth, nheight );
734 }
735
736 /* Video widget cannot do this synchronously as it runs in another thread */
737 /* Well, could it, actually ? Probably dangerous ... */
738
739 /* This function is called:
740    - toggling of minimal View
741    - through askUpdate() by Vout thread request video and resize video (zoom)
742    - Advanced buttons toggled
743  */
744 void MainInterface::doComponentsUpdate()
745 {
746     if( isFullScreen() || isMaximized() ) return;
747
748     msg_Dbg( p_intf, "Updating the geometry" );
749     /* Here we resize to sizeHint() and not adjustsize because we want
750        the videoWidget to be exactly the correctSize */
751     resize( sizeHint() );
752     //    adjustSize()  ;
753 #ifndef NDEBUG
754     debug();
755 #endif
756 }
757
758 void MainInterface::debug()
759 {
760 #ifndef NDEBUG
761     msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
762     msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
763     if( videoWidget && videoWidget->isVisible() )
764     {
765         msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
766         msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
767     }
768 #endif
769 }
770
771 void MainInterface::destroyPopupMenu()
772 {
773     QVLCMenu::PopupMenu(p_intf, false );
774 }
775
776
777 void MainInterface::toggleFSC()
778 {
779    if( !fullscreenControls ) return;
780
781    IMEvent *eShow = new IMEvent( FullscreenControlToggle_Type, 0 );
782    QApplication::postEvent( fullscreenControls, eShow );
783 }
784
785 void MainInterface::popupMenu( const QPoint &p )
786 {
787     /* Ow, that's ugly: don't show the popup menu if cursor over
788      * the main menu bar or the status bar */
789     if( !childAt( p ) || ( ( childAt( p ) != menuBar() )
790                         && ( childAt( p )->parentWidget() != statusBar() ) ) )
791         QVLCMenu::PopupMenu( p_intf, true );
792 }
793
794 /****************************************************************************
795  * Video Handling
796  ****************************************************************************/
797
798 /* This event is used to deal with the fullscreen and always on top
799    issue conflict (bug in wx) */
800 class SetVideoOnTopQtEvent : public QEvent
801 {
802 public:
803     SetVideoOnTopQtEvent( bool _onTop ) :
804       QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
805     {}
806
807     bool OnTop() const { return onTop; }
808
809 private:
810     bool onTop;
811 };
812
813 /**
814  * NOTE:
815  * You must note change the state of this object or other Qt4 UI objects,
816  * from the video output thread - only from the Qt4 UI main loop thread.
817  * All window provider queries must be handled through signals or events.
818  * That's why we have all those emit statements...
819  */
820 WId MainInterface::getVideo( int *pi_x, int *pi_y,
821                              unsigned int *pi_width, unsigned int *pi_height )
822 {
823     if( !videoWidget )
824         return 0;
825
826     /* This is a blocking call signal. Results are returned through pointers.
827      * Beware of deadlocks! */
828     WId id;
829     emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
830     return id;
831 }
832
833 void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
834                                   unsigned *pi_width, unsigned *pi_height )
835 {
836     /* Request the videoWidget */
837     WId ret = videoWidget->request( pi_x, pi_y,
838                                     pi_width, pi_height, b_keep_size );
839     *p_id = ret;
840     if( ret ) /* The videoWidget is available */
841     {
842         /* Did we have a bg ? Hide it! */
843         if( VISIBLE( bgWidget) )
844         {
845             bgWasVisible = true;
846             bgWidget->toggle();
847         }
848         else
849             bgWasVisible = false;
850
851         /* ask videoWidget to show */
852         videoWidget->SetSizing( *pi_width, *pi_height );
853
854         /* Consider the video active now */
855         videoIsActive = true;
856
857         emit askUpdate();
858     }
859 }
860
861 /* Asynchronous call from the WindowClose function */
862 void MainInterface::releaseVideo( void )
863 {
864     emit askReleaseVideo( );
865 }
866
867 /* Function that is CONNECTED to the previous emit */
868 void MainInterface::releaseVideoSlot( void )
869 {
870     videoWidget->release( );
871
872     if( bgWasVisible )
873     {
874         /* Reset the bg state */
875         bgWasVisible = false;
876         bgWidget->show();
877     }
878
879     videoIsActive = false;
880
881     /* Try to resize, except when you are in Fullscreen mode */
882     doComponentsUpdate();
883 }
884
885 /* Asynchronous call from WindowControl function */
886 int MainInterface::controlVideo( int i_query, va_list args )
887 {
888     switch( i_query )
889     {
890     case VOUT_WINDOW_SET_SIZE:
891     {
892         unsigned int i_width  = va_arg( args, unsigned int );
893         unsigned int i_height = va_arg( args, unsigned int );
894         emit askVideoToResize( i_width, i_height );
895         emit askUpdate();
896         return VLC_SUCCESS;
897     }
898     case VOUT_WINDOW_SET_ON_TOP:
899     {
900         int i_arg = va_arg( args, int );
901         QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
902         return VLC_SUCCESS;
903     }
904     case VOUT_WINDOW_SET_FULLSCREEN:
905     {
906         bool b_fs = va_arg( args, int );
907         emit askVideoSetFullScreen( b_fs );
908         return VLC_SUCCESS;
909     }
910     default:
911         msg_Warn( p_intf, "unsupported control query" );
912         return VLC_EGENERIC;
913     }
914 }
915
916 /*****************************************************************************
917  * Playlist, Visualisation and Menus handling
918  *****************************************************************************/
919 /**
920  * Toggle the playlist widget or dialog
921  **/
922 void MainInterface::togglePlaylist()
923 {
924     /* CREATION
925     If no playlist exist, then create one and attach it to the DockPL*/
926     if( !playlistWidget )
927     {
928         playlistWidget = new PlaylistWidget( p_intf );
929
930         i_pl_dock = PL_UNDOCKED;
931 /*        i_pl_dock = (pl_dock_e)getSettings()
932                          ->value( "pl-dock-status", PL_UNDOCKED ).toInt(); */
933
934         if( i_pl_dock == PL_UNDOCKED )
935         {
936             playlistWidget->setWindowFlags( Qt::Window );
937
938             /* This will restore the geometry but will not work for position,
939                because of parenting */
940             QVLCTools::restoreWidgetPosition( p_intf, "Playlist",
941                     playlistWidget, QSize( 600, 300 ) );
942         }
943         else
944         {
945          //   mainLayout->insertWidget( 4, playlistWidget );
946         }
947         playlistVisible = true;
948
949         playlistWidget->show();
950     }
951     else
952     {
953     /* toggle the visibility of the playlist */
954        TOGGLEV( playlistWidget );
955        playlistVisible = !playlistVisible;
956        //doComponentsUpdate(); //resize( sizeHint() );
957     }
958 }
959
960 /* Function called from the menu to undock the playlist */
961 void MainInterface::undockPlaylist()
962 {
963 //    dockPL->setFloating( true );
964 //    adjustSize();
965 }
966
967 void MainInterface::dockPlaylist( pl_dock_e i_pos )
968 {
969 }
970
971 void MainInterface::toggleMinimalView( bool b_switch )
972 {
973     if( i_visualmode != QT_ALWAYS_VIDEO_MODE &&
974         i_visualmode != QT_MINIMAL_MODE )
975     { /* NORMAL MODE then */
976         if( !videoWidget || videoWidget->isHidden() )
977         {
978             bgWidget->toggle();
979         }
980         else
981         {
982             /* If video is visible, then toggle the status of bgWidget */
983             bgWasVisible = !bgWasVisible;
984         }
985     }
986
987     i_bg_height = bgWidget->height();
988
989     menuBar()->setVisible( !b_switch );
990     controls->setVisible( !b_switch );
991     statusBar()->setVisible( !b_switch );
992     inputC->setVisible( !b_switch );
993
994     doComponentsUpdate();
995
996     emit minimalViewToggled( b_switch );
997 }
998
999 /* toggling advanced controls buttons */
1000 void MainInterface::toggleAdvanced()
1001 {
1002     controls->toggleAdvanced();
1003 //    if( fullscreenControls ) fullscreenControls->toggleAdvanced();
1004 }
1005
1006 /* Get the visibility status of the controls (hidden or not, advanced or not) */
1007 int MainInterface::getControlsVisibilityStatus()
1008 {
1009     return( (controls->isVisible() ? CONTROLS_VISIBLE : CONTROLS_HIDDEN )
1010                 + CONTROLS_ADVANCED * controls->b_advancedVisible );
1011 }
1012
1013 #if 0
1014 void MainInterface::visual()
1015 {
1016     if( !VISIBLE( visualSelector) )
1017     {
1018         visualSelector->show();
1019         if( !THEMIM->getIM()->hasVideo() )
1020         {
1021             /* Show the background widget */
1022         }
1023         visualSelectorEnabled = true;
1024     }
1025     else
1026     {
1027         /* Stop any currently running visualization */
1028         visualSelector->hide();
1029         visualSelectorEnabled = false;
1030     }
1031     doComponentsUpdate();
1032 }
1033 #endif
1034
1035 /************************************************************************
1036  * Other stuff
1037  ************************************************************************/
1038 void MainInterface::setName( const QString& name )
1039 {
1040     input_name = name; /* store it for the QSystray use */
1041     /* Display it in the status bar, but also as a Tooltip in case it doesn't
1042        fit in the label */
1043     nameLabel->setText( " " + name + " " );
1044     nameLabel->setToolTip( " " + name +" " );
1045 }
1046
1047 /**
1048  * Give the decorations of the Main Window a correct Name.
1049  * If nothing is given, set it to VLC...
1050  **/
1051 void MainInterface::setVLCWindowsTitle( const QString& aTitle )
1052 {
1053     if( aTitle.isEmpty() )
1054     {
1055         setWindowTitle( qtr( "VLC media player" ) );
1056     }
1057     else
1058     {
1059         setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
1060     }
1061 }
1062
1063 void MainInterface::showCryptedLabel( bool b_show )
1064 {
1065     if( cryptedLabel == NULL )
1066     {
1067         cryptedLabel = new QLabel;
1068         // The lock icon is not the right one for DRM protection/scrambled.
1069         //cryptedLabel->setPixmap( QPixmap( ":/lock" ) );
1070         cryptedLabel->setText( "DRM" );
1071         statusBar()->addWidget( cryptedLabel );
1072     }
1073
1074     cryptedLabel->setVisible( b_show );
1075 }
1076
1077 /*****************************************************************************
1078  * Systray Icon and Systray Menu
1079  *****************************************************************************/
1080
1081 /**
1082  * Create a SystemTray icon and a menu that would go with it.
1083  * Connects to a click handler on the icon.
1084  **/
1085 void MainInterface::createSystray()
1086 {
1087     QIcon iconVLC;
1088     if( QDate::currentDate().dayOfYear() >= 354 )
1089         iconVLC =  QIcon( QPixmap( ":/logo/vlc128-christmas.png" ) );
1090     else
1091         iconVLC =  QIcon( QPixmap( ":/logo/vlc128.png" ) );
1092     sysTray = new QSystemTrayIcon( iconVLC, this );
1093     sysTray->setToolTip( qtr( "VLC media player" ));
1094
1095     systrayMenu = new QMenu( qtr( "VLC media player" ), this );
1096     systrayMenu->setIcon( iconVLC );
1097
1098     QVLCMenu::updateSystrayMenu( this, p_intf, true );
1099     sysTray->show();
1100
1101     CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ),
1102             this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
1103 }
1104
1105 /**
1106  * Updates the Systray Icon's menu and toggle the main interface
1107  */
1108 void MainInterface::toggleUpdateSystrayMenu()
1109 {
1110     /* If hidden, show it */
1111     if( isHidden() )
1112     {
1113         show();
1114         activateWindow();
1115     }
1116     else if( isMinimized() )
1117     {
1118         /* Minimized */
1119         showNormal();
1120         activateWindow();
1121     }
1122     else
1123     {
1124         /* Visible (possibly under other windows) */
1125 #ifdef WIN32
1126         /* check if any visible window is above vlc in the z-order,
1127          * but ignore the ones always on top
1128          * and the ones which can't be activated */
1129         WINDOWINFO wi;
1130         HWND hwnd;
1131         wi.cbSize = sizeof( WINDOWINFO );
1132         for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
1133                 hwnd && ( !IsWindowVisible( hwnd ) ||
1134                     ( GetWindowInfo( hwnd, &wi ) &&
1135                       (wi.dwExStyle&WS_EX_NOACTIVATE) ) );
1136                 hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
1137             if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
1138                 (wi.dwExStyle&WS_EX_TOPMOST) )
1139             {
1140                 hide();
1141             }
1142             else
1143             {
1144                 activateWindow();
1145             }
1146 #else
1147         hide();
1148 #endif
1149     }
1150     QVLCMenu::updateSystrayMenu( this, p_intf );
1151 }
1152
1153 void MainInterface::handleSystrayClick(
1154                                     QSystemTrayIcon::ActivationReason reason )
1155 {
1156     switch( reason )
1157     {
1158         case QSystemTrayIcon::Trigger:
1159         case QSystemTrayIcon::DoubleClick:
1160             toggleUpdateSystrayMenu();
1161             break;
1162         case QSystemTrayIcon::MiddleClick:
1163             sysTray->showMessage( qtr( "VLC media player" ),
1164                     qtr( "Control menu for the player" ),
1165                     QSystemTrayIcon::Information, 3000 );
1166             break;
1167         default:
1168             break;
1169     }
1170 }
1171
1172 /**
1173  * Updates the name of the systray Icon tooltip.
1174  * Doesn't check if the systray exists, check before you call it.
1175  **/
1176 void MainInterface::updateSystrayTooltipName( const QString& name )
1177 {
1178     if( name.isEmpty() )
1179     {
1180         sysTray->setToolTip( qtr( "VLC media player" ) );
1181     }
1182     else
1183     {
1184         sysTray->setToolTip( name );
1185         if( notificationEnabled && ( isHidden() || isMinimized() ) )
1186         {
1187             sysTray->showMessage( qtr( "VLC media player" ), name,
1188                     QSystemTrayIcon::NoIcon, 3000 );
1189         }
1190     }
1191
1192     QVLCMenu::updateSystrayMenu( this, p_intf );
1193 }
1194
1195 /**
1196  * Updates the status of the systray Icon tooltip.
1197  * Doesn't check if the systray exists, check before you call it.
1198  **/
1199 void MainInterface::updateSystrayTooltipStatus( int i_status )
1200 {
1201     switch( i_status )
1202     {
1203         case  0:
1204         case  END_S:
1205             {
1206                 sysTray->setToolTip( qtr( "VLC media player" ) );
1207                 break;
1208             }
1209         case PLAYING_S:
1210             {
1211                 sysTray->setToolTip( input_name );
1212                 break;
1213             }
1214         case PAUSE_S:
1215             {
1216                 sysTray->setToolTip( input_name + " - "
1217                         + qtr( "Paused") );
1218                 break;
1219             }
1220     }
1221     QVLCMenu::updateSystrayMenu( this, p_intf );
1222 }
1223
1224 /************************************************************************
1225  * D&D Events
1226  ************************************************************************/
1227 void MainInterface::dropEvent(QDropEvent *event)
1228 {
1229     dropEventPlay( event, true );
1230 }
1231
1232 void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
1233 {
1234      event->setDropAction( Qt::CopyAction );
1235      if( !event->possibleActions() & Qt::CopyAction )
1236          return;
1237
1238      const QMimeData *mimeData = event->mimeData();
1239
1240      /* D&D of a subtitles file, add it on the fly */
1241      if( mimeData->urls().size() == 1 )
1242      {
1243         if( THEMIM->getIM()->hasInput() )
1244         {
1245             if( !input_AddSubtitle( THEMIM->getInput(),
1246                                     qtu( toNativeSeparators(
1247                                          mimeData->urls()[0].toLocalFile() ) ),
1248                                     true ) )
1249             {
1250                 event->accept();
1251                 return;
1252             }
1253         }
1254      }
1255      bool first = b_play;
1256      foreach( const QUrl &url, mimeData->urls() )
1257      {
1258         QString s = toNativeSeparators( url.toLocalFile() );
1259
1260         if( s.length() > 0 ) {
1261             char* psz_uri = make_URI( qtu(s) );
1262             playlist_Add( THEPL, psz_uri, NULL,
1263                           PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
1264                           PLAYLIST_END, true, pl_Unlocked );
1265             free( psz_uri );
1266             first = false;
1267             RecentsMRL::getInstance( p_intf )->addRecent( s );
1268         }
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::customEvent( QEvent *event )
1289 {
1290 #if 0
1291     if( event->type() == PLDockEvent_Type )
1292     {
1293         PlaylistDialog::killInstance();
1294         playlistEmbeddedFlag = true;
1295         menuBar()->clear();
1296         QVLCMenu::createMenuBar(this, p_intf, true, visualSelectorEnabled);
1297         togglePlaylist();
1298     }
1299 #endif
1300     /*else */
1301     if ( event->type() == (int)SetVideoOnTopEvent_Type )
1302     {
1303         SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event;
1304         if( p_event->OnTop() )
1305             setWindowFlags( windowFlags() | Qt::WindowStaysOnTopHint );
1306         else
1307             setWindowFlags( windowFlags() & ~Qt::WindowStaysOnTopHint );
1308         show(); /* necessary to apply window flags */
1309     }
1310 }
1311
1312 void MainInterface::keyPressEvent( QKeyEvent *e )
1313 {
1314     handleKeyPress( e );
1315 }
1316
1317 void MainInterface::handleKeyPress( QKeyEvent *e )
1318 {
1319     if( ( e->modifiers() &  Qt::ControlModifier ) && ( e->key() == Qt::Key_H )
1320           && !menuBar()->isVisible() )
1321     {
1322         toggleMinimalView( false );
1323         e->accept();
1324     }
1325
1326     int i_vlck = qtEventToVLCKey( e );
1327     if( i_vlck > 0 )
1328     {
1329         var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
1330         e->accept();
1331     }
1332     else
1333         e->ignore();
1334 }
1335
1336 void MainInterface::resizeEvent( QResizeEvent * event )
1337 {
1338     if( b_keep_size )
1339     {
1340         if( i_visualmode == QT_ALWAYS_VIDEO_MODE ||
1341             i_visualmode == QT_MINIMAL_MODE )
1342         {
1343                 mainVideoSize = size();
1344         }
1345         else
1346         {
1347             if( VISIBLE( bgWidget) ||
1348                 ( videoIsActive && videoWidget->isVisible() )
1349               )
1350                 mainVideoSize = size();
1351             else
1352                 mainBasedSize = size();
1353         }
1354     }
1355 }
1356
1357 void MainInterface::wheelEvent( QWheelEvent *e )
1358 {
1359     int i_vlckey = qtWheelEventToVLCKey( e );
1360     var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
1361     e->accept();
1362 }
1363
1364 void MainInterface::closeEvent( QCloseEvent *e )
1365 {
1366     e->accept();
1367     hide();
1368     THEDP->quit();
1369 }
1370
1371 void MainInterface::toggleFullScreen( void )
1372 {
1373     if( isFullScreen() )
1374     {
1375         showNormal();
1376         emit askUpdate(); // Needed if video was launched after the F11
1377         emit fullscreenInterfaceToggled( false );
1378     }
1379     else
1380     {
1381         showFullScreen();
1382         emit fullscreenInterfaceToggled( true );
1383     }
1384
1385 }
1386
1387 //moc doesn't know about #ifdef, so we have to build this method for every platform
1388 void MainInterface::changeThumbbarButtons( int i_status)
1389 {
1390 #ifdef WIN32
1391     // Define an array of two buttons. These buttons provide images through an
1392     // image list and also provide tooltips.
1393     DWORD dwMask = THB_BITMAP | THB_FLAGS;
1394
1395     THUMBBUTTON thbButtons[3];
1396     //prev
1397     thbButtons[0].dwMask = dwMask;
1398     thbButtons[0].iId = 0;
1399     thbButtons[0].iBitmap = 0;
1400
1401     //play/pause
1402     thbButtons[1].dwMask = dwMask;
1403     thbButtons[1].iId = 1;
1404
1405     //next
1406     thbButtons[2].dwMask = dwMask;
1407     thbButtons[2].iId = 2;
1408     thbButtons[2].iBitmap = 3;
1409
1410     switch( i_status )
1411     {
1412         case  0:
1413         case  END_S:
1414             {
1415                 thbButtons[0].dwFlags = THBF_HIDDEN;
1416                 thbButtons[1].dwFlags = THBF_HIDDEN;
1417                 thbButtons[2].dwFlags = THBF_HIDDEN;
1418                 break;
1419             }
1420         case PLAYING_S:
1421             {
1422                 thbButtons[0].dwFlags = THBF_ENABLED;
1423                 thbButtons[1].dwFlags = THBF_ENABLED;
1424                 thbButtons[2].dwFlags = THBF_ENABLED;
1425                 thbButtons[1].iBitmap = 1;
1426                 break;
1427             }
1428         case PAUSE_S:
1429             {
1430                 //thbButtons[0].dwFlags = THBF_ENABLED;
1431                 //thbButtons[1].dwFlags = THBF_ENABLED;
1432                 //thbButtons[2].dwFlags = THBF_ENABLED;
1433                 thbButtons[1].iBitmap = 2;
1434                 break;
1435             }
1436     }
1437
1438     HRESULT hr =  p_taskbl->vt->ThumbBarUpdateButtons(p_taskbl, GetForegroundWindow(), 3, thbButtons);
1439     if(S_OK != hr)
1440         msg_Err( p_intf, "ThumbBarUpdateButtons failed with error %08x", hr );
1441 #else
1442     ;
1443 #endif
1444 }
1445
1446 /*****************************************************************************
1447  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
1448  *  We don't show the menu directly here because we don't want the
1449  *  caller to block for a too long time.
1450  *****************************************************************************/
1451 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
1452                         vlc_value_t old_val, vlc_value_t new_val, void *param )
1453 {
1454     intf_thread_t *p_intf = (intf_thread_t *)param;
1455
1456     if( p_intf->pf_show_dialog )
1457     {
1458         p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
1459                                 new_val.b_bool, NULL );
1460     }
1461
1462     return VLC_SUCCESS;
1463 }
1464
1465 /*****************************************************************************
1466  * IntfShowCB: callback triggered by the intf-show libvlc variable.
1467  *****************************************************************************/
1468 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
1469                        vlc_value_t old_val, vlc_value_t new_val, void *param )
1470 {
1471     intf_thread_t *p_intf = (intf_thread_t *)param;
1472     p_intf->p_sys->p_mi->toggleFSC();
1473
1474     /* Show event */
1475      return VLC_SUCCESS;
1476 }
1477