]> git.sesse.net Git - vlc/blobdiff - modules/gui/wxwindows/video.cpp
* modules/gui/wxwindows/*: workaround uninitialization bug in wxWidgets -> re-enabled...
[vlc] / modules / gui / wxwindows / video.cpp
index 0dd25b5e5d0c57b60e2724ec47922f72a4156994..c498d2c3e376ea248f1af6efa25ec987e70d9fba 100644 (file)
@@ -2,7 +2,7 @@
  * video.cpp : wxWindows plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2004, 2003 VideoLAN
- * $Id: interface.cpp 6961 2004-03-05 17:34:23Z sam $
+ * $Id$
  *
  * Authors: Gildas Bazin <gbazin@videolan.org>
  *
 #include <vlc/vlc.h>
 #include <vlc/vout.h>
 #include <vlc/intf.h>
-#include "stream_control.h"
 
 #include "wxwindows.h"
 
-static void *GetWindow( intf_thread_t *p_intf, int *pi_x_hint, int *pi_y_hint,
+static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
+                        int *pi_x_hint, int *pi_y_hint,
                         unsigned int *pi_width_hint,
                         unsigned int *pi_height_hint );
+
 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
 
+static int ControlWindow( intf_thread_t *p_intf, void *p_window,
+                          int i_query, va_list args );
+
 /* IDs for the controls and the menu commands */
 enum
 {
     UpdateSize_Event = wxID_HIGHEST + 1,
-    UpdateHide_Event
+    UpdateHide_Event,
+    SetStayOnTop_Event,
+    ID_HIDE_TIMER
 };
 
 class VideoWindow: public wxWindow
@@ -50,34 +56,55 @@ public:
     VideoWindow( intf_thread_t *_p_intf, wxWindow *p_parent );
     virtual ~VideoWindow();
 
-    void *GetWindow( int *, int *, unsigned int *, unsigned int * );
+    void *GetWindow( vout_thread_t *p_vout, int *, int *,
+                     unsigned int *, unsigned int * );
     void ReleaseWindow( void * );
+    int  ControlWindow( void *, int, va_list );
 
 private:
     intf_thread_t *p_intf;
+    vout_thread_t *p_vout;
     wxWindow *p_parent;
     vlc_mutex_t lock;
-    vlc_bool_t  b_in_use;
+    vlc_bool_t b_shown;
+    vlc_bool_t b_auto_size;
 
     wxWindow *p_child_window;
 
-    void UpdateSize( wxSizeEvent & );
-    void UpdateHide( wxSizeEvent & );
+    wxTimer m_hide_timer;
+
+    void UpdateSize( wxEvent& event );
+    void UpdateHide( wxEvent& event );
+    void OnControlEvent( wxCommandEvent& event );
+    void OnHideTimer( wxTimerEvent& WXUNUSED(event));
 
     DECLARE_EVENT_TABLE();
 };
 
+DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
+
 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
     EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
     EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
+    EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
+                 VideoWindow::OnControlEvent )
+    EVT_TIMER( ID_HIDE_TIMER, VideoWindow::OnHideTimer )
 END_EVENT_TABLE()
 
 /*****************************************************************************
  * Public methods.
  *****************************************************************************/
-wxWindow *VideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
+wxWindow *CreateVideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
 {
-    return new VideoWindow::VideoWindow( p_intf, p_parent );
+    return new VideoWindow( p_intf, p_parent );
+}
+
+void UpdateVideoWindow( intf_thread_t *p_intf, wxWindow *p_window )
+{
+#if (wxCHECK_VERSION(2,5,0))
+    if( p_window && p_intf->p_sys->p_video_sizer && p_window->IsShown() )
+        p_intf->p_sys->p_video_sizer->SetMinSize( p_window->GetSize() );
+#endif
 }
 
 /*****************************************************************************
@@ -91,35 +118,97 @@ VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
     p_parent = _p_parent;
 
     vlc_mutex_init( p_intf, &lock );
-    b_in_use = VLC_FALSE;
+
+    b_auto_size = config_GetInt( p_intf, "wxwin-autosize" );
+
+    p_vout = NULL;
+
+    m_hide_timer.SetOwner( this, ID_HIDE_TIMER );
 
     p_intf->pf_request_window = ::GetWindow;
     p_intf->pf_release_window = ::ReleaseWindow;
+    p_intf->pf_control_window = ::ControlWindow;
 
     p_intf->p_sys->p_video_window = this;
-    p_child_window = new wxWindow( this, -1, wxDefaultPosition, wxSize(0,0) );
+
+    wxSize child_size = wxSize(0,0);
+    if( !b_auto_size )
+    {
+        WindowSettings *ws = p_intf->p_sys->p_window_settings;
+        wxPoint p; bool b_shown;
+
+        // Maybe this size should be an option
+        child_size = wxSize( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) / 2,
+                             wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) / 2 );
+
+        ws->GetSettings( WindowSettings::ID_VIDEO, b_shown, p, child_size );
+        SetSize( child_size );
+    }
+
+    p_child_window = new wxWindow( this, -1, wxDefaultPosition, child_size );
+
+    if( !b_auto_size )
+    {
+        SetBackgroundColour( *wxBLACK );
+        p_child_window->SetBackgroundColour( *wxBLACK );
+    }
+
     p_child_window->Show();
     Show();
+    b_shown = VLC_TRUE;
 
     p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
+#if (wxCHECK_VERSION(2,5,3))
+    p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND|wxFIXED_MINSIZE );
+#else
     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
+#endif
 
     ReleaseWindow( NULL );
 }
 
 VideoWindow::~VideoWindow()
 {
+    vlc_mutex_lock( &lock );
+    if( p_vout )
+    {
+        if( !p_intf->psz_switch_intf )
+        {
+            if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
+                vout_Control( p_vout, VOUT_REPARENT );
+        }
+        else
+        {
+            if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
+                vout_Control( p_vout, VOUT_CLOSE );
+        }
+    }
+
+    p_intf->pf_request_window = NULL;
+    p_intf->pf_release_window = NULL;
+    p_intf->pf_control_window = NULL;
+    vlc_mutex_unlock( &lock );
+
+    if( !b_auto_size )
+    {
+        WindowSettings *ws = p_intf->p_sys->p_window_settings;
+        ws->SetSettings( WindowSettings::ID_VIDEO, true,
+                         GetPosition(), GetSize() );
+    }
+
     vlc_mutex_destroy( &lock );
 }
 
 /*****************************************************************************
  * Private methods.
  *****************************************************************************/
-static void *GetWindow( intf_thread_t *p_intf, int *pi_x_hint, int *pi_y_hint,
+static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
+                        int *pi_x_hint, int *pi_y_hint,
                         unsigned int *pi_width_hint,
                         unsigned int *pi_height_hint )
 {
-    return p_intf->p_sys->p_video_window->GetWindow( pi_x_hint, pi_y_hint,
+    return p_intf->p_sys->p_video_window->GetWindow( p_vout,
+                                                     pi_x_hint, pi_y_hint,
                                                      pi_width_hint,
                                                      pi_height_hint );
 }
@@ -134,23 +223,25 @@ extern "C" {
 }
 #endif
 
-void *VideoWindow::GetWindow( int *pi_x_hint, int *pi_y_hint,
+void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
+                              int *pi_x_hint, int *pi_y_hint,
                               unsigned int *pi_width_hint,
                               unsigned int *pi_height_hint )
 {
 #if defined(__WXGTK__) || defined(WIN32)
     vlc_mutex_lock( &lock );
 
-    if( b_in_use )
+    if( p_vout )
     {
+        vlc_mutex_unlock( &lock );
         msg_Dbg( p_intf, "Video window already in use" );
         return NULL;
     }
 
-    b_in_use = VLC_TRUE;
+    p_vout = _p_vout;
 
     wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
-                      UpdateSize_Event );
+                       UpdateSize_Event );
     AddPendingEvent( event );
     vlc_mutex_unlock( &lock );
 
@@ -184,40 +275,119 @@ static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
 void VideoWindow::ReleaseWindow( void *p_window )
 {
     vlc_mutex_lock( &lock );
+    p_vout = NULL;
+    vlc_mutex_unlock( &lock );
 
-    b_in_use = VLC_FALSE;
+    if( !b_auto_size ) return;
 
 #if defined(__WXGTK__) || defined(WIN32)
     wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
     AddPendingEvent( event );
 #endif
-
-    vlc_mutex_unlock( &lock );
 }
 
-void VideoWindow::UpdateSize( wxSizeEvent &event )
+void VideoWindow::UpdateSize( wxEvent &_event )
 {
-    if( !IsShown() )
+    m_hide_timer.Stop();
+
+    if( !b_auto_size ) return;
+
+    wxSizeEvent * event = (wxSizeEvent*)(&_event);
+    if( !b_shown )
     {
         p_intf->p_sys->p_video_sizer->Show( this, TRUE );
         p_intf->p_sys->p_video_sizer->Layout();
         SetFocus();
+        b_shown = VLC_TRUE;
     }
-    p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
+    p_intf->p_sys->p_video_sizer->SetMinSize( event->GetSize() );
 
     wxCommandEvent intf_event( wxEVT_INTF, 0 );
     p_parent->AddPendingEvent( intf_event );
 }
 
-void VideoWindow::UpdateHide( wxSizeEvent &event )
+void VideoWindow::UpdateHide( wxEvent &_event )
 {
-    if( IsShown() )
+    if( b_auto_size ) m_hide_timer.Start( 200, wxTIMER_ONE_SHOT );
+}
+
+void VideoWindow::OnHideTimer( wxTimerEvent& WXUNUSED(event))
+{
+    if( b_shown )
     {
         p_intf->p_sys->p_video_sizer->Show( this, FALSE );
+        SetSize( 0, 0 );
         p_intf->p_sys->p_video_sizer->Layout();
+        b_shown = VLC_FALSE;
     }
-    p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
+    p_intf->p_sys->p_video_sizer->SetMinSize( wxSize(0,0) );
 
     wxCommandEvent intf_event( wxEVT_INTF, 0 );
     p_parent->AddPendingEvent( intf_event );
 }
+
+void VideoWindow::OnControlEvent( wxCommandEvent &event )
+{
+    switch( event.GetId() )
+    {
+    case SetStayOnTop_Event:
+        wxCommandEvent intf_event( wxEVT_INTF, 1 );
+        intf_event.SetInt( event.GetInt() );
+        p_parent->AddPendingEvent( intf_event );
+        break;
+    }
+}
+
+static int ControlWindow( intf_thread_t *p_intf, void *p_window,
+                          int i_query, va_list args )
+{
+    return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
+                                                         args );
+}
+
+int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
+{
+    int i_ret = VLC_EGENERIC;
+
+    vlc_mutex_lock( &lock );
+
+    switch( i_query )
+    {
+        case VOUT_SET_ZOOM:
+        {
+            if( !b_auto_size ) break;
+
+            double f_arg = va_arg( args, double );
+
+            /* Update dimensions */
+            wxSizeEvent event( wxSize((int)(p_vout->i_window_width * f_arg),
+                                      (int)(p_vout->i_window_height * f_arg)),
+                               UpdateSize_Event );
+
+              
+            AddPendingEvent( event );
+
+            i_ret = VLC_SUCCESS;
+        }
+        break;
+
+        case VOUT_SET_STAY_ON_TOP:
+        {
+            int i_arg = va_arg( args, int );
+            wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
+            event.SetInt( i_arg );
+            AddPendingEvent( event );
+
+            i_ret = VLC_SUCCESS;
+        }
+        break;
+
+        default:
+            msg_Dbg( p_intf, "control query not supported" );
+            break;
+    }
+
+    vlc_mutex_unlock( &lock );
+
+    return i_ret;
+}