Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

video.cpp

00001 /*****************************************************************************
00002  * video.cpp : wxWidgets plugin for vlc
00003  *****************************************************************************
00004  * Copyright (C) 2000-2004, 2003 the VideoLAN team
00005  * $Id: video.cpp 13051 2005-10-31 07:35:39Z md $
00006  *
00007  * Authors: Gildas Bazin <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/vout.h>
00029 #include <vlc/intf.h>
00030 
00031 #include "wxwidgets.h"
00032 
00033 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
00034                         int *pi_x_hint, int *pi_y_hint,
00035                         unsigned int *pi_width_hint,
00036                         unsigned int *pi_height_hint );
00037 
00038 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
00039 
00040 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
00041                           int i_query, va_list args );
00042 
00043 /* IDs for the controls and the menu commands */
00044 enum
00045 {
00046     UpdateSize_Event = wxID_HIGHEST + 1,
00047     UpdateHide_Event,
00048     SetStayOnTop_Event,
00049     ID_HIDE_TIMER
00050 };
00051 
00052 class VideoWindow: public wxWindow
00053 {
00054 public:
00055     /* Constructor */
00056     VideoWindow( intf_thread_t *_p_intf, wxWindow *p_parent );
00057     virtual ~VideoWindow();
00058 
00059     void *GetWindow( vout_thread_t *p_vout, int *, int *,
00060                      unsigned int *, unsigned int * );
00061     void ReleaseWindow( void * );
00062     int  ControlWindow( void *, int, va_list );
00063 
00064     mtime_t i_creation_date;
00065 
00066 private:
00067     intf_thread_t *p_intf;
00068     vout_thread_t *p_vout;
00069     wxWindow *p_parent;
00070     vlc_mutex_t lock;
00071     vlc_bool_t b_shown;
00072     vlc_bool_t b_auto_size;
00073 
00074     wxWindow *p_child_window;
00075 
00076     wxTimer m_hide_timer;
00077 
00078     void UpdateSize( wxEvent& event );
00079     void UpdateHide( wxEvent& event );
00080     void OnControlEvent( wxCommandEvent& event );
00081     void OnHideTimer( wxTimerEvent& WXUNUSED(event));
00082 
00083     DECLARE_EVENT_TABLE();
00084 };
00085 
00086 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
00087 
00088 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
00089     EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
00090     EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
00091     EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
00092                  VideoWindow::OnControlEvent )
00093     EVT_TIMER( ID_HIDE_TIMER, VideoWindow::OnHideTimer )
00094 END_EVENT_TABLE()
00095 
00096 /*****************************************************************************
00097  * Public methods.
00098  *****************************************************************************/
00099 wxWindow *CreateVideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
00100 {
00101     return new VideoWindow( p_intf, p_parent );
00102 }
00103 
00104 void UpdateVideoWindow( intf_thread_t *p_intf, wxWindow *p_window )
00105 {
00106 #if (wxCHECK_VERSION(2,5,0))
00107     if( p_window && mdate() - ((VideoWindow *)p_window)->i_creation_date < 2000000 )
00108         return; /* Hack to prevent saving coordinates if window is not yet
00109                  * properly created. Yuck :( */
00110 
00111     if( p_window && p_intf->p_sys->p_video_sizer && p_window->IsShown() )
00112         p_intf->p_sys->p_video_sizer->SetMinSize( p_window->GetSize() );
00113 #endif
00114 }
00115 
00116 /*****************************************************************************
00117  * Constructor.
00118  *****************************************************************************/
00119 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
00120     wxWindow( _p_parent, -1 )
00121 {
00122     /* Initializations */
00123     p_intf = _p_intf;
00124     p_parent = _p_parent;
00125 
00126     vlc_mutex_init( p_intf, &lock );
00127 
00128     b_auto_size = config_GetInt( p_intf, "wx-autosize" );
00129 
00130     p_vout = NULL;
00131     i_creation_date = 0;
00132     m_hide_timer.SetOwner( this, ID_HIDE_TIMER );
00133 
00134     p_intf->pf_request_window = ::GetWindow;
00135     p_intf->pf_release_window = ::ReleaseWindow;
00136     p_intf->pf_control_window = ::ControlWindow;
00137 
00138     p_intf->p_sys->p_video_window = this;
00139 
00140     wxSize child_size = wxSize(0,0);
00141     if( !b_auto_size )
00142     {
00143         WindowSettings *ws = p_intf->p_sys->p_window_settings;
00144         wxPoint p; bool b_shown;
00145 
00146         // Maybe this size should be an option
00147         child_size = wxSize( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) / 2,
00148                              wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) / 2 );
00149 
00150         ws->GetSettings( WindowSettings::ID_VIDEO, b_shown, p, child_size );
00151         SetSize( child_size );
00152     }
00153 
00154     p_child_window = new wxWindow( this, -1, wxDefaultPosition, child_size );
00155 
00156     if( !b_auto_size )
00157     {
00158         SetBackgroundColour( *wxBLACK );
00159         p_child_window->SetBackgroundColour( *wxBLACK );
00160     }
00161 
00162     p_child_window->Show();
00163     Show();
00164     b_shown = VLC_TRUE;
00165 
00166     p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
00167 #if (wxCHECK_VERSION(2,5,3))
00168     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND|wxFIXED_MINSIZE );
00169 #else
00170     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
00171 #endif
00172 
00173     ReleaseWindow( NULL );
00174 }
00175 
00176 VideoWindow::~VideoWindow()
00177 {
00178     vlc_mutex_lock( &lock );
00179     if( p_vout )
00180     {
00181         if( !p_intf->psz_switch_intf )
00182         {
00183             if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
00184                 vout_Control( p_vout, VOUT_REPARENT );
00185         }
00186         else
00187         {
00188             if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
00189                 vout_Control( p_vout, VOUT_CLOSE );
00190         }
00191     }
00192 
00193     p_intf->pf_request_window = NULL;
00194     p_intf->pf_release_window = NULL;
00195     p_intf->pf_control_window = NULL;
00196     vlc_mutex_unlock( &lock );
00197 
00198     if( !b_auto_size )
00199     {
00200         WindowSettings *ws = p_intf->p_sys->p_window_settings;
00201         ws->SetSettings( WindowSettings::ID_VIDEO, true,
00202                          GetPosition(), GetSize() );
00203     }
00204 
00205     vlc_mutex_destroy( &lock );
00206 }
00207 
00208 /*****************************************************************************
00209  * Private methods.
00210  *****************************************************************************/
00211 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
00212                         int *pi_x_hint, int *pi_y_hint,
00213                         unsigned int *pi_width_hint,
00214                         unsigned int *pi_height_hint )
00215 {
00216     return p_intf->p_sys->p_video_window->GetWindow( p_vout,
00217                                                      pi_x_hint, pi_y_hint,
00218                                                      pi_width_hint,
00219                                                      pi_height_hint );
00220 }
00221 
00222 /* Part of the hack to get the X11 window handle from the GtkWidget */
00223 #ifdef __WXGTK__
00224 extern "C" {
00225 #ifdef __WXGTK20__
00226     int gdk_x11_drawable_get_xid( void * );
00227 #endif
00228     void *gtk_widget_get_parent_window( void * );
00229 }
00230 #endif
00231 
00232 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
00233                               int *pi_x_hint, int *pi_y_hint,
00234                               unsigned int *pi_width_hint,
00235                               unsigned int *pi_height_hint )
00236 {
00237 #if defined(__WXGTK__) || defined(WIN32)
00238     vlc_mutex_lock( &lock );
00239 
00240     if( p_vout )
00241     {
00242         vlc_mutex_unlock( &lock );
00243         msg_Dbg( p_intf, "Video window already in use" );
00244         return NULL;
00245     }
00246 
00247     p_vout = _p_vout;
00248 
00249     wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
00250                        UpdateSize_Event );
00251     AddPendingEvent( event );
00252     vlc_mutex_unlock( &lock );
00253 
00254 #ifdef __WXGTK__
00255     GtkWidget *p_widget = p_child_window->GetHandle();
00256 
00257 #ifdef __WXGTK20__
00258     return (void *)gdk_x11_drawable_get_xid(
00259                gtk_widget_get_parent_window( p_widget ) );
00260 #elif defined(__WXGTK__)
00261     return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
00262                + 2 * sizeof(void *) );
00263 #endif
00264 
00265 #elif defined(WIN32)
00266     return (void*)GetHandle();
00267 
00268 #endif
00269 
00270 #else // defined(__WXGTK__) || defined(WIN32)
00271     return NULL;
00272 
00273 #endif
00274 }
00275 
00276 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
00277 {
00278     return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
00279 }
00280 
00281 void VideoWindow::ReleaseWindow( void *p_window )
00282 {
00283     vlc_mutex_lock( &lock );
00284     p_vout = NULL;
00285     vlc_mutex_unlock( &lock );
00286 
00287     if( !b_auto_size ) return;
00288 
00289 #if defined(__WXGTK__) || defined(WIN32)
00290     wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
00291     AddPendingEvent( event );
00292 #endif
00293 }
00294 
00295 void VideoWindow::UpdateSize( wxEvent &_event )
00296 {
00297     m_hide_timer.Stop();
00298 
00299     if( !b_auto_size ) return;
00300 
00301     wxSizeEvent * event = (wxSizeEvent*)(&_event);
00302     if( !b_shown )
00303     {
00304         p_intf->p_sys->p_video_sizer->Show( this, TRUE );
00305         p_intf->p_sys->p_video_sizer->Layout();
00306         SetFocus();
00307         b_shown = VLC_TRUE;
00308     }
00309     p_intf->p_sys->p_video_sizer->SetMinSize( event->GetSize() );
00310 
00311     i_creation_date = mdate();
00312     wxCommandEvent intf_event( wxEVT_INTF, 0 );
00313     p_parent->AddPendingEvent( intf_event );
00314 }
00315 
00316 void VideoWindow::UpdateHide( wxEvent &_event )
00317 {
00318     if( b_auto_size ) m_hide_timer.Start( 200, wxTIMER_ONE_SHOT );
00319 }
00320 
00321 void VideoWindow::OnHideTimer( wxTimerEvent& WXUNUSED(event))
00322 {
00323     if( b_shown )
00324     {
00325         p_intf->p_sys->p_video_sizer->Show( this, FALSE );
00326         SetSize( 0, 0 );
00327         p_intf->p_sys->p_video_sizer->Layout();
00328         b_shown = VLC_FALSE;
00329     }
00330     p_intf->p_sys->p_video_sizer->SetMinSize( wxSize(0,0) );
00331 
00332     wxCommandEvent intf_event( wxEVT_INTF, 0 );
00333     p_parent->AddPendingEvent( intf_event );
00334 }
00335 
00336 void VideoWindow::OnControlEvent( wxCommandEvent &event )
00337 {
00338     switch( event.GetId() )
00339     {
00340     case SetStayOnTop_Event:
00341         wxCommandEvent intf_event( wxEVT_INTF, 1 );
00342         intf_event.SetInt( event.GetInt() );
00343         p_parent->AddPendingEvent( intf_event );
00344         break;
00345     }
00346 }
00347 
00348 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
00349                           int i_query, va_list args )
00350 {
00351     return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
00352                                                          args );
00353 }
00354 
00355 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
00356 {
00357     int i_ret = VLC_EGENERIC;
00358 
00359     vlc_mutex_lock( &lock );
00360 
00361     switch( i_query )
00362     {
00363         case VOUT_SET_ZOOM:
00364         {
00365             if( !b_auto_size ) break;
00366 
00367             /* Update dimensions */
00368             wxSizeEvent event( wxSize( p_vout->i_window_width,
00369                                        p_vout->i_window_height ),
00370                                UpdateSize_Event );
00371 
00372               
00373             AddPendingEvent( event );
00374 
00375             i_ret = VLC_SUCCESS;
00376         }
00377         break;
00378 
00379         case VOUT_SET_STAY_ON_TOP:
00380         {
00381             int i_arg = va_arg( args, int );
00382             wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
00383             event.SetInt( i_arg );
00384             AddPendingEvent( event );
00385 
00386             i_ret = VLC_SUCCESS;
00387         }
00388         break;
00389 
00390         default:
00391             msg_Dbg( p_intf, "control query not supported" );
00392             break;
00393     }
00394 
00395     vlc_mutex_unlock( &lock );
00396 
00397     return i_ret;
00398 }

Generated on Tue Dec 20 10:14:47 2005 for vlc-0.8.4a by  doxygen 1.4.2