]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/main_interface.cpp
Qt4: fix race in requestVideo and simplify
[vlc] / modules / gui / qt4 / main_interface.cpp
index 7a8ea0f75ad5fa8808fc86820a72caf98823a6ff..715d2fe0674893c9a049eef9e3df7bb0c0cbb75f 100644 (file)
@@ -61,6 +61,7 @@
 #include <assert.h>
 
 #include <vlc_keys.h> /* Wheel event */
+#include <vlc_vout_window.h>
 #include <vlc_vout.h>
 
 /* Callback prototypes */
@@ -215,18 +216,18 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
     var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
 
 
-    /* VideoWidget connects to avoid different threads speaking to each other */
+    /* VideoWidget connects for asynchronous calls */
+    connect( this, SIGNAL(askGetVideo(WId*,int*,int*,unsigned*,unsigned *)),
+             this, SLOT(getVideoSlot(WId*,int*,int*,unsigned*,unsigned*)),
+             Qt::BlockingQueuedConnection );
     connect( this, SIGNAL(askReleaseVideo( void )),
-             this, SLOT(releaseVideoSlot( void )), Qt::BlockingQueuedConnection );
+             this, SLOT(releaseVideoSlot( void )),
+             Qt::BlockingQueuedConnection );
 
     if( videoWidget )
     {
         CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
                  videoWidget, SetSizing( unsigned int, unsigned int ) );
-
-        connect( this, SIGNAL(askVideoToShow( unsigned int, unsigned int)),
-             videoWidget, SLOT(SetSizing(unsigned int, unsigned int )),
-             Qt::BlockingQueuedConnection );
     }
 
     CONNECT( this, askUpdate(), this, doComponentsUpdate() );
@@ -372,7 +373,6 @@ void MainInterface::createMainWidget( QSettings *settings )
     bgWidget->resize(
             settings->value( "backgroundSize", QSize( 300, 200 ) ).toSize() );
     bgWidget->updateGeometry();
-    CONNECT( this, askBgWidgetToToggle(), bgWidget, toggle() );
 
     if( i_visualmode != QT_ALWAYS_VIDEO_MODE &&
         i_visualmode != QT_MINIMAL_MODE )
@@ -702,41 +702,54 @@ private:
 };
 
 /**
- * README
- * Thou shall not call/resize/hide widgets from on another thread.
- * This is wrong, and this is THE reason to emit signals on those Video Functions
- **/
-WId MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
-                                 int *pi_y, unsigned int *pi_width,
-                                 unsigned int *pi_height )
+ * NOTE:
+ * You must note change the state of this object or other Qt4 UI objects,
+ * from the video output thread - only from the Qt4 UI main loop thread.
+ * All window provider queries must be handled through signals or events.
+ * That's why we have all those emit statements...
+ */
+WId MainInterface::getVideo( int *pi_x, int *pi_y,
+                             unsigned int *pi_width, unsigned int *pi_height )
+{
+    if( !videoWidget )
+        return 0;
+
+    /* This is a blocking call signal. Results are returned through pointers.
+     * Beware of deadlocks! */
+    WId id;
+    emit askGetVideo( &id, pi_x, pi_y, pi_width, pi_height );
+    return id;
+}
+
+void MainInterface::getVideoSlot( WId *p_id, int *pi_x, int *pi_y,
+                                  unsigned *pi_width, unsigned *pi_height )
 {
     /* Request the videoWidget */
-    if( !videoWidget ) return 0;
-    WId ret = videoWidget->request( p_nvout,pi_x, pi_y,
+    WId ret = videoWidget->request( pi_x, pi_y,
                                     pi_width, pi_height, b_keep_size );
+    *p_id = ret;
     if( ret ) /* The videoWidget is available */
     {
         /* Did we have a bg ? Hide it! */
         if( VISIBLE( bgWidget) )
         {
             bgWasVisible = true;
-            emit askBgWidgetToToggle();
+            bgWidget->toggle();
         }
         else
             bgWasVisible = false;
 
         /* ask videoWidget to show */
-        emit askVideoToShow( *pi_width, *pi_height );
+        videoWidget->SetSizing( *pi_width, *pi_height );
 
         /* Consider the video active now */
         videoIsActive = true;
 
         emit askUpdate();
     }
-    return ret;
 }
 
-/* Call from the WindowClose function */
+/* Asynchronous call from the WindowClose function */
 void MainInterface::releaseVideo( void )
 {
     emit askReleaseVideo( );
@@ -760,32 +773,29 @@ void MainInterface::releaseVideoSlot( void )
     doComponentsUpdate();
 }
 
-/* Call from WindowControl function */
+/* Asynchronous call from WindowControl function */
 int MainInterface::controlVideo( int i_query, va_list args )
 {
-    int i_ret = VLC_SUCCESS;
     switch( i_query )
     {
-        case VOUT_SET_SIZE:
-        {
-            unsigned int i_width  = va_arg( args, unsigned int );
-            unsigned int i_height = va_arg( args, unsigned int );
-            emit askVideoToResize( i_width, i_height );
-            emit askUpdate();
-            break;
-        }
-        case VOUT_SET_STAY_ON_TOP:
-        {
-            int i_arg = va_arg( args, int );
-            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
-            break;
-        }
-        default:
-            i_ret = VLC_EGENERIC;
-            msg_Warn( p_intf, "unsupported control query" );
-            break;
+    case VOUT_WINDOW_SET_SIZE:
+    {
+        unsigned int i_width  = va_arg( args, unsigned int );
+        unsigned int i_height = va_arg( args, unsigned int );
+        emit askVideoToResize( i_width, i_height );
+        emit askUpdate();
+        return VLC_SUCCESS;
+    }
+    case VOUT_WINDOW_SET_ON_TOP:
+    {
+        int i_arg = va_arg( args, int );
+        QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
+        return VLC_SUCCESS;
+    }
+    default:
+        msg_Warn( p_intf, "unsupported control query" );
+        return VLC_EGENERIC;
     }
-    return i_ret;
 }
 
 /*****************************************************************************
@@ -850,7 +860,7 @@ void MainInterface::toggleMinimalView( bool b_switch )
     { /* NORMAL MODE then */
         if( !videoWidget || videoWidget->isHidden() )
         {
-            emit askBgWidgetToToggle();
+            bgWidget->toggle();
         }
         else
         {
@@ -1134,8 +1144,8 @@ void MainInterface::dropEventPlay( QDropEvent *event, bool b_play )
 
         if( s.length() > 0 ) {
             playlist_Add( THEPL, qtu(s), NULL,
-                          PLAYLIST_APPEND | PLAYLIST_PREPARSE | (first ? PLAYLIST_GO: 0),
-                          PLAYLIST_END, true, false );
+                          PLAYLIST_APPEND | (first ? PLAYLIST_GO: PLAYLIST_PREPARSE),
+                          PLAYLIST_END, true, pl_Unlocked );
             first = false;
             RecentsMRL::getInstance( p_intf )->addRecent( s );
         }