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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
31 #include <vlc_common.h>
33 #include <vlc_interface.h>
36 #include "interface.hpp"
38 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
39 int *pi_x_hint, int *pi_y_hint,
40 unsigned int *pi_width_hint,
41 unsigned int *pi_height_hint );
43 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
45 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
46 int i_query, va_list args );
48 /* IDs for the controls and the menu commands */
51 UpdateSize_Event = wxID_HIGHEST + 1,
57 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
59 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
60 EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
61 EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
62 EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
63 VideoWindow::OnControlEvent )
64 EVT_TIMER( ID_HIDE_TIMER, VideoWindow::OnHideTimer )
67 /*****************************************************************************
69 *****************************************************************************/
70 wxWindow *CreateVideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
72 return new VideoWindow( p_intf, p_parent );
75 void UpdateVideoWindow( intf_thread_t *p_intf, wxWindow *p_window )
77 #if wxCHECK_VERSION(2,5,3)
78 if( !p_intf->p_sys->b_video_autosize ) return;
80 if( p_window && mdate() - ((VideoWindow *)p_window)->i_creation_date < 2000000 )
81 return; /* Hack to prevent saving coordinates if window is not yet
82 * properly created. Yuck :( */
84 if( p_window && p_intf->p_sys->p_video_sizer && p_window->IsShown() )
85 p_intf->p_sys->p_video_sizer->SetMinSize( p_window->GetSize() );
89 /*****************************************************************************
91 *****************************************************************************/
92 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
93 wxWindow( _p_parent, -1, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN )
100 vlc_mutex_init( &lock );
102 b_auto_size = p_intf->p_sys->b_video_autosize;
106 m_hide_timer.SetOwner( this, ID_HIDE_TIMER );
108 p_intf->pf_request_window = ::GetWindow;
109 p_intf->pf_release_window = ::ReleaseWindow;
110 p_intf->pf_control_window = ::ControlWindow;
112 p_intf->p_sys->p_video_window = this;
114 wxSize child_size = wxSize(0,0);
117 WindowSettings *ws = p_intf->p_sys->p_window_settings;
118 wxPoint p; bool b_shown;
120 // Maybe this size should be an option
121 child_size = wxSize( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) / 2,
122 wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) / 2 );
124 ws->GetSettings( WindowSettings::ID_VIDEO, b_shown, p, child_size );
125 SetSize( child_size );
129 p_child_window = new wxWindow( this, -1, wxDefaultPosition, child_size,
135 SetBackgroundColour( *wxBLACK );
136 if( p_child_window ) p_child_window->SetBackgroundColour( *wxBLACK );
139 if( p_child_window ) p_child_window->Show();
143 p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
144 #if (wxCHECK_VERSION(2,5,3))
145 p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND|wxFIXED_MINSIZE );
147 p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
150 ReleaseWindow( NULL );
153 VideoWindow::~VideoWindow()
155 vlc_mutex_lock( &lock );
158 if( !p_intf->psz_switch_intf )
160 if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
161 vout_Control( p_vout, VOUT_REPARENT, 0 );
165 if( vout_Control( p_vout, VOUT_REPARENT, 0 ) != VLC_SUCCESS )
166 vout_Control( p_vout, VOUT_CLOSE );
170 p_intf->pf_request_window = NULL;
171 p_intf->pf_release_window = NULL;
172 p_intf->pf_control_window = NULL;
173 vlc_mutex_unlock( &lock );
177 WindowSettings *ws = p_intf->p_sys->p_window_settings;
178 ws->SetSettings( WindowSettings::ID_VIDEO, true,
179 GetPosition(), GetSize() );
182 vlc_mutex_destroy( &lock );
185 /*****************************************************************************
187 *****************************************************************************/
188 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
189 int *pi_x_hint, int *pi_y_hint,
190 unsigned int *pi_width_hint,
191 unsigned int *pi_height_hint )
193 return p_intf->p_sys->p_video_window->GetWindow( p_vout,
194 pi_x_hint, pi_y_hint,
199 /* Part of the hack to get the X11 window handle from the GtkWidget */
203 int gdk_x11_drawable_get_xid( void * );
205 void *gtk_widget_get_parent_window( void * );
209 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
210 int *pi_x_hint, int *pi_y_hint,
211 unsigned int *pi_width_hint,
212 unsigned int *pi_height_hint )
214 #if defined(__WXGTK__) || defined(WIN32)
215 vlc_mutex_lock( &lock );
219 vlc_mutex_unlock( &lock );
220 msg_Dbg( p_intf, "video window already in use" );
226 wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
228 AddPendingEvent( event );
229 vlc_mutex_unlock( &lock );
232 GtkWidget *p_widget = p_child_window->GetHandle();
235 return (void *)gdk_x11_drawable_get_xid(
236 gtk_widget_get_parent_window( p_widget ) );
237 #elif defined(__WXGTK__)
238 return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
239 + 2 * sizeof(void *) );
243 return (void*)GetHandle();
247 #else // defined(__WXGTK__) || defined(WIN32)
253 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
255 return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
258 void VideoWindow::ReleaseWindow( void *p_window )
260 vlc_mutex_lock( &lock );
262 vlc_mutex_unlock( &lock );
264 if( !b_auto_size ) return;
266 #if defined(__WXGTK__) || defined(WIN32)
267 wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
268 AddPendingEvent( event );
272 void VideoWindow::UpdateSize( wxEvent &_event )
276 if( !b_auto_size ) return;
278 wxSizeEvent * event = (wxSizeEvent*)(&_event);
281 p_intf->p_sys->p_video_sizer->Show( this, TRUE );
282 p_intf->p_sys->p_video_sizer->Layout();
287 p_intf->p_sys->p_video_sizer->SetMinSize( event->GetSize() );
289 i_creation_date = mdate();
290 wxCommandEvent intf_event( wxEVT_INTF, 0 );
291 p_parent->AddPendingEvent( intf_event );
294 void VideoWindow::UpdateHide( wxEvent &_event )
296 if( b_auto_size ) m_hide_timer.Start( 200, wxTIMER_ONE_SHOT );
299 void VideoWindow::OnHideTimer( wxTimerEvent& WXUNUSED(event))
303 p_intf->p_sys->p_video_sizer->Show( this, FALSE );
305 p_intf->p_sys->p_video_sizer->Layout();
308 p_intf->p_sys->p_video_sizer->SetMinSize( wxSize(0,0) );
310 wxCommandEvent intf_event( wxEVT_INTF, 0 );
311 p_parent->AddPendingEvent( intf_event );
314 void VideoWindow::OnControlEvent( wxCommandEvent &event )
316 switch( event.GetId() )
318 case SetStayOnTop_Event:
319 wxCommandEvent intf_event( wxEVT_INTF, 1 );
320 intf_event.SetInt( event.GetInt() );
321 p_parent->AddPendingEvent( intf_event );
326 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
327 int i_query, va_list args )
329 return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
333 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
335 int i_ret = VLC_EGENERIC;
337 vlc_mutex_lock( &lock );
343 unsigned int *pi_width = va_arg( args, unsigned int * );
344 unsigned int *pi_height = va_arg( args, unsigned int * );
346 *pi_width = GetSize().GetWidth();
347 *pi_height = GetSize().GetHeight();
354 if( !b_auto_size ) break;
356 unsigned int i_width = va_arg( args, unsigned int );
357 unsigned int i_height = va_arg( args, unsigned int );
359 if( !i_width && p_vout ) i_width = p_vout->i_window_width;
360 if( !i_height && p_vout ) i_height = p_vout->i_window_height;
362 /* Update dimensions */
363 wxSizeEvent event( wxSize( i_width, i_height ), UpdateSize_Event );
365 AddPendingEvent( event );
371 case VOUT_SET_STAY_ON_TOP:
373 int i_arg = va_arg( args, int );
374 wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
375 event.SetInt( i_arg );
376 AddPendingEvent( event );
383 msg_Dbg( p_intf, "control query not supported" );
387 vlc_mutex_unlock( &lock );