00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
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;
00109
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
00118
00119 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
00120 wxWindow( _p_parent, -1 )
00121 {
00122
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
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
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
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
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 }