1 /*****************************************************************************
2 * video.cpp : wxWindows plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2004, 2003 VideoLAN
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 "wxwindows.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,
51 class VideoWindow: public wxWindow
55 VideoWindow( intf_thread_t *_p_intf, wxWindow *p_parent );
56 virtual ~VideoWindow();
58 void *GetWindow( vout_thread_t *p_vout, int *, int *,
59 unsigned int *, unsigned int * );
60 void ReleaseWindow( void * );
61 int ControlWindow( void *, int, va_list );
64 intf_thread_t *p_intf;
65 vout_thread_t *p_vout;
69 wxWindow *p_child_window;
71 void UpdateSize( wxSizeEvent & );
72 void UpdateHide( wxSizeEvent & );
73 void OnControlEvent( wxCommandEvent & );
75 DECLARE_EVENT_TABLE();
78 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
80 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
81 EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
82 EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
83 EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
84 VideoWindow::OnControlEvent )
87 /*****************************************************************************
89 *****************************************************************************/
90 wxWindow *VideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
92 return new VideoWindow::VideoWindow( p_intf, p_parent );
95 /*****************************************************************************
97 *****************************************************************************/
98 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
99 wxWindow( _p_parent, -1 )
101 /* Initializations */
103 p_parent = _p_parent;
105 vlc_mutex_init( p_intf, &lock );
109 p_intf->pf_request_window = ::GetWindow;
110 p_intf->pf_release_window = ::ReleaseWindow;
111 p_intf->pf_control_window = ::ControlWindow;
113 p_intf->p_sys->p_video_window = this;
114 p_child_window = new wxWindow( this, -1, wxDefaultPosition, wxSize(0,0) );
115 p_child_window->Show();
118 p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
119 p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
121 ReleaseWindow( NULL );
124 VideoWindow::~VideoWindow()
126 vlc_mutex_lock( &lock );
129 if( !p_intf->psz_switch_intf )
131 if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
132 vout_Control( p_vout, VOUT_REPARENT );
136 if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
137 vout_Control( p_vout, VOUT_CLOSE );
141 p_intf->pf_request_window = NULL;
142 p_intf->pf_release_window = NULL;
143 p_intf->pf_control_window = NULL;
144 vlc_mutex_unlock( &lock );
146 vlc_mutex_destroy( &lock );
149 /*****************************************************************************
151 *****************************************************************************/
152 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
153 int *pi_x_hint, int *pi_y_hint,
154 unsigned int *pi_width_hint,
155 unsigned int *pi_height_hint )
157 return p_intf->p_sys->p_video_window->GetWindow( p_vout,
158 pi_x_hint, pi_y_hint,
163 /* Part of the hack to get the X11 window handle from the GtkWidget */
167 int gdk_x11_drawable_get_xid( void * );
169 void *gtk_widget_get_parent_window( void * );
173 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
174 int *pi_x_hint, int *pi_y_hint,
175 unsigned int *pi_width_hint,
176 unsigned int *pi_height_hint )
178 #if defined(__WXGTK__) || defined(WIN32)
179 vlc_mutex_lock( &lock );
183 vlc_mutex_unlock( &lock );
184 msg_Dbg( p_intf, "Video window already in use" );
190 wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
192 AddPendingEvent( event );
193 vlc_mutex_unlock( &lock );
196 GtkWidget *p_widget = p_child_window->GetHandle();
199 return (void *)gdk_x11_drawable_get_xid(
200 gtk_widget_get_parent_window( p_widget ) );
201 #elif defined(__WXGTK__)
202 return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
203 + 2 * sizeof(void *) );
207 return (void*)GetHandle();
211 #else // defined(__WXGTK__) || defined(WIN32)
217 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
219 return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
222 void VideoWindow::ReleaseWindow( void *p_window )
224 vlc_mutex_lock( &lock );
228 #if defined(__WXGTK__) || defined(WIN32)
229 wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
230 AddPendingEvent( event );
233 vlc_mutex_unlock( &lock );
236 void VideoWindow::UpdateSize( wxSizeEvent &event )
240 p_intf->p_sys->p_video_sizer->Show( this, TRUE );
241 p_intf->p_sys->p_video_sizer->Layout();
244 p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
246 wxCommandEvent intf_event( wxEVT_INTF, 0 );
247 p_parent->AddPendingEvent( intf_event );
250 void VideoWindow::UpdateHide( wxSizeEvent &event )
254 p_intf->p_sys->p_video_sizer->Show( this, FALSE );
255 p_intf->p_sys->p_video_sizer->Layout();
257 p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
259 wxCommandEvent intf_event( wxEVT_INTF, 0 );
260 p_parent->AddPendingEvent( intf_event );
263 void VideoWindow::OnControlEvent( wxCommandEvent &event )
265 switch( event.GetId() )
267 case SetStayOnTop_Event:
268 wxCommandEvent intf_event( wxEVT_INTF, 1 );
269 intf_event.SetInt( event.GetInt() );
270 p_parent->AddPendingEvent( intf_event );
275 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
276 int i_query, va_list args )
278 return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
282 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
284 int i_ret = VLC_EGENERIC;
286 vlc_mutex_lock( &lock );
292 double f_arg = va_arg( args, double );
294 /* Update dimensions */
295 wxSizeEvent event( wxSize(p_vout->i_window_width * f_arg,
296 p_vout->i_window_height * f_arg),
298 AddPendingEvent( event );
304 case VOUT_SET_STAY_ON_TOP:
306 int i_arg = va_arg( args, int );
307 wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
308 event.SetInt( i_arg );
309 AddPendingEvent( event );
316 msg_Dbg( p_intf, "control query not supported" );
320 vlc_mutex_unlock( &lock );