1 /*****************************************************************************
2 * video.cpp : wxWidgets plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2004, 2003 the VideoLAN team
7 * Authors: Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include "wxwidgets.h"
33 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
34 int *pi_x_hint, int *pi_y_hint,
35 unsigned int *pi_width_hint,
36 unsigned int *pi_height_hint );
38 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
40 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
41 int i_query, va_list args );
43 /* IDs for the controls and the menu commands */
46 UpdateSize_Event = wxID_HIGHEST + 1,
52 class VideoWindow: public wxWindow
56 VideoWindow( intf_thread_t *_p_intf, wxWindow *p_parent );
57 virtual ~VideoWindow();
59 void *GetWindow( vout_thread_t *p_vout, int *, int *,
60 unsigned int *, unsigned int * );
61 void ReleaseWindow( void * );
62 int ControlWindow( void *, int, va_list );
64 mtime_t i_creation_date;
67 intf_thread_t *p_intf;
68 vout_thread_t *p_vout;
72 vlc_bool_t b_auto_size;
74 wxWindow *p_child_window;
78 void UpdateSize( wxEvent& event );
79 void UpdateHide( wxEvent& event );
80 void OnControlEvent( wxCommandEvent& event );
81 void OnHideTimer( wxTimerEvent& WXUNUSED(event));
83 DECLARE_EVENT_TABLE();
86 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
88 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
89 EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
90 EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
91 EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
92 VideoWindow::OnControlEvent )
93 EVT_TIMER( ID_HIDE_TIMER, VideoWindow::OnHideTimer )
96 /*****************************************************************************
98 *****************************************************************************/
99 wxWindow *CreateVideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
101 return new VideoWindow( p_intf, p_parent );
104 void UpdateVideoWindow( intf_thread_t *p_intf, wxWindow *p_window )
106 #if (wxCHECK_VERSION(2,5,0))
107 if( p_window && mdate() - ((VideoWindow *)p_window)->i_creation_date < 2000000 )
108 return; /* Hack to prevent saving coordinates if window is not yet
109 * properly created. Yuck :( */
111 if( p_window && p_intf->p_sys->p_video_sizer && p_window->IsShown() )
112 p_intf->p_sys->p_video_sizer->SetMinSize( p_window->GetSize() );
116 /*****************************************************************************
118 *****************************************************************************/
119 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
120 wxWindow( _p_parent, -1 )
122 /* Initializations */
124 p_parent = _p_parent;
126 vlc_mutex_init( p_intf, &lock );
128 b_auto_size = config_GetInt( p_intf, "wx-autosize" );
132 m_hide_timer.SetOwner( this, ID_HIDE_TIMER );
134 p_intf->pf_request_window = ::GetWindow;
135 p_intf->pf_release_window = ::ReleaseWindow;
136 p_intf->pf_control_window = ::ControlWindow;
138 p_intf->p_sys->p_video_window = this;
140 wxSize child_size = wxSize(0,0);
143 WindowSettings *ws = p_intf->p_sys->p_window_settings;
144 wxPoint p; bool b_shown;
146 // Maybe this size should be an option
147 child_size = wxSize( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) / 2,
148 wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) / 2 );
150 ws->GetSettings( WindowSettings::ID_VIDEO, b_shown, p, child_size );
151 SetSize( child_size );
154 p_child_window = new wxWindow( this, -1, wxDefaultPosition, child_size );
158 SetBackgroundColour( *wxBLACK );
159 p_child_window->SetBackgroundColour( *wxBLACK );
162 p_child_window->Show();
166 p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
167 #if (wxCHECK_VERSION(2,5,3))
168 p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND|wxFIXED_MINSIZE );
170 p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
173 ReleaseWindow( NULL );
176 VideoWindow::~VideoWindow()
178 vlc_mutex_lock( &lock );
181 if( !p_intf->psz_switch_intf )
183 if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
184 vout_Control( p_vout, VOUT_REPARENT );
188 if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
189 vout_Control( p_vout, VOUT_CLOSE );
193 p_intf->pf_request_window = NULL;
194 p_intf->pf_release_window = NULL;
195 p_intf->pf_control_window = NULL;
196 vlc_mutex_unlock( &lock );
200 WindowSettings *ws = p_intf->p_sys->p_window_settings;
201 ws->SetSettings( WindowSettings::ID_VIDEO, true,
202 GetPosition(), GetSize() );
205 vlc_mutex_destroy( &lock );
208 /*****************************************************************************
210 *****************************************************************************/
211 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
212 int *pi_x_hint, int *pi_y_hint,
213 unsigned int *pi_width_hint,
214 unsigned int *pi_height_hint )
216 return p_intf->p_sys->p_video_window->GetWindow( p_vout,
217 pi_x_hint, pi_y_hint,
222 /* Part of the hack to get the X11 window handle from the GtkWidget */
226 int gdk_x11_drawable_get_xid( void * );
228 void *gtk_widget_get_parent_window( void * );
232 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
233 int *pi_x_hint, int *pi_y_hint,
234 unsigned int *pi_width_hint,
235 unsigned int *pi_height_hint )
237 #if defined(__WXGTK__) || defined(WIN32)
238 vlc_mutex_lock( &lock );
242 vlc_mutex_unlock( &lock );
243 msg_Dbg( p_intf, "Video window already in use" );
249 wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
251 AddPendingEvent( event );
252 vlc_mutex_unlock( &lock );
255 GtkWidget *p_widget = p_child_window->GetHandle();
258 return (void *)gdk_x11_drawable_get_xid(
259 gtk_widget_get_parent_window( p_widget ) );
260 #elif defined(__WXGTK__)
261 return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
262 + 2 * sizeof(void *) );
266 return (void*)GetHandle();
270 #else // defined(__WXGTK__) || defined(WIN32)
276 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
278 return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
281 void VideoWindow::ReleaseWindow( void *p_window )
283 vlc_mutex_lock( &lock );
285 vlc_mutex_unlock( &lock );
287 if( !b_auto_size ) return;
289 #if defined(__WXGTK__) || defined(WIN32)
290 wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
291 AddPendingEvent( event );
295 void VideoWindow::UpdateSize( wxEvent &_event )
299 if( !b_auto_size ) return;
301 wxSizeEvent * event = (wxSizeEvent*)(&_event);
304 p_intf->p_sys->p_video_sizer->Show( this, TRUE );
305 p_intf->p_sys->p_video_sizer->Layout();
309 p_intf->p_sys->p_video_sizer->SetMinSize( event->GetSize() );
311 i_creation_date = mdate();
312 wxCommandEvent intf_event( wxEVT_INTF, 0 );
313 p_parent->AddPendingEvent( intf_event );
316 void VideoWindow::UpdateHide( wxEvent &_event )
318 if( b_auto_size ) m_hide_timer.Start( 200, wxTIMER_ONE_SHOT );
321 void VideoWindow::OnHideTimer( wxTimerEvent& WXUNUSED(event))
325 p_intf->p_sys->p_video_sizer->Show( this, FALSE );
327 p_intf->p_sys->p_video_sizer->Layout();
330 p_intf->p_sys->p_video_sizer->SetMinSize( wxSize(0,0) );
332 wxCommandEvent intf_event( wxEVT_INTF, 0 );
333 p_parent->AddPendingEvent( intf_event );
336 void VideoWindow::OnControlEvent( wxCommandEvent &event )
338 switch( event.GetId() )
340 case SetStayOnTop_Event:
341 wxCommandEvent intf_event( wxEVT_INTF, 1 );
342 intf_event.SetInt( event.GetInt() );
343 p_parent->AddPendingEvent( intf_event );
348 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
349 int i_query, va_list args )
351 return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
355 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
357 int i_ret = VLC_EGENERIC;
359 vlc_mutex_lock( &lock );
365 if( !b_auto_size ) break;
367 double f_arg = va_arg( args, double );
369 /* Update dimensions */
370 wxSizeEvent event( wxSize((int)(p_vout->i_window_width * f_arg),
371 (int)(p_vout->i_window_height * f_arg)),
375 AddPendingEvent( event );
381 case VOUT_SET_STAY_ON_TOP:
383 int i_arg = va_arg( args, int );
384 wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
385 event.SetInt( i_arg );
386 AddPendingEvent( event );
393 msg_Dbg( p_intf, "control query not supported" );
397 vlc_mutex_unlock( &lock );