]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/video.cpp
Fix x264 compilation
[vlc] / modules / gui / wxwidgets / video.cpp
1 /*****************************************************************************
2  * video.cpp : wxWidgets plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004, 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc/vout.h>
29 #include <vlc/intf.h>
30
31 #include "video.hpp"
32 #include "interface.hpp"
33
34 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *,
35                         int *pi_x_hint, int *pi_y_hint,
36                         unsigned int *pi_width_hint,
37                         unsigned int *pi_height_hint );
38
39 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
40
41 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
42                           int i_query, va_list args );
43
44 /* IDs for the controls and the menu commands */
45 enum
46 {
47     UpdateSize_Event = wxID_HIGHEST + 1,
48     UpdateHide_Event,
49     SetStayOnTop_Event,
50     ID_HIDE_TIMER
51 };
52
53 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
54
55 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
56     EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
57     EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
58     EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
59                  VideoWindow::OnControlEvent )
60     EVT_TIMER( ID_HIDE_TIMER, VideoWindow::OnHideTimer )
61 END_EVENT_TABLE()
62
63 /*****************************************************************************
64  * Public methods.
65  *****************************************************************************/
66 wxWindow *CreateVideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
67 {
68     return new VideoWindow( p_intf, p_parent );
69 }
70
71 void UpdateVideoWindow( intf_thread_t *p_intf, wxWindow *p_window )
72 {
73 #if (wxCHECK_VERSION(2,5,0))
74     if( p_window && mdate() - ((VideoWindow *)p_window)->i_creation_date < 2000000 )
75         return; /* Hack to prevent saving coordinates if window is not yet
76                  * properly created. Yuck :( */
77
78     if( p_window && p_intf->p_sys->p_video_sizer && p_window->IsShown() )
79         p_intf->p_sys->p_video_sizer->SetMinSize( p_window->GetSize() );
80 #endif
81 }
82
83 /*****************************************************************************
84  * Constructor.
85  *****************************************************************************/
86 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
87     wxWindow( _p_parent, -1 )
88 {
89     /* Initializations */
90     p_intf = _p_intf;
91     p_parent = _p_parent;
92
93     vlc_mutex_init( p_intf, &lock );
94
95     b_auto_size = config_GetInt( p_intf, "wx-autosize" );
96
97     p_vout = NULL;
98     i_creation_date = 0;
99     m_hide_timer.SetOwner( this, ID_HIDE_TIMER );
100
101     p_intf->pf_request_window = ::GetWindow;
102     p_intf->pf_release_window = ::ReleaseWindow;
103     p_intf->pf_control_window = ::ControlWindow;
104
105     p_intf->p_sys->p_video_window = this;
106
107     wxSize child_size = wxSize(0,0);
108     if( !b_auto_size )
109     {
110         WindowSettings *ws = p_intf->p_sys->p_window_settings;
111         wxPoint p; bool b_shown;
112
113         // Maybe this size should be an option
114         child_size = wxSize( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) / 2,
115                              wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) / 2 );
116
117         ws->GetSettings( WindowSettings::ID_VIDEO, b_shown, p, child_size );
118         SetSize( child_size );
119     }
120
121     p_child_window = new wxWindow( this, -1, wxDefaultPosition, child_size );
122
123     if( !b_auto_size )
124     {
125         SetBackgroundColour( *wxBLACK );
126         p_child_window->SetBackgroundColour( *wxBLACK );
127     }
128
129     p_child_window->Show();
130     Show();
131     b_shown = VLC_TRUE;
132
133     p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
134 #if (wxCHECK_VERSION(2,5,3))
135     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND|wxFIXED_MINSIZE );
136 #else
137     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
138 #endif
139
140     ReleaseWindow( NULL );
141 }
142
143 VideoWindow::~VideoWindow()
144 {
145     vlc_mutex_lock( &lock );
146     if( p_vout )
147     {
148         if( !p_intf->psz_switch_intf )
149         {
150             if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
151                 vout_Control( p_vout, VOUT_REPARENT );
152         }
153         else
154         {
155             if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
156                 vout_Control( p_vout, VOUT_CLOSE );
157         }
158     }
159
160     p_intf->pf_request_window = NULL;
161     p_intf->pf_release_window = NULL;
162     p_intf->pf_control_window = NULL;
163     vlc_mutex_unlock( &lock );
164
165     if( !b_auto_size )
166     {
167         WindowSettings *ws = p_intf->p_sys->p_window_settings;
168         ws->SetSettings( WindowSettings::ID_VIDEO, true,
169                          GetPosition(), GetSize() );
170     }
171
172     vlc_mutex_destroy( &lock );
173 }
174
175 /*****************************************************************************
176  * Private methods.
177  *****************************************************************************/
178 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
179                         int *pi_x_hint, int *pi_y_hint,
180                         unsigned int *pi_width_hint,
181                         unsigned int *pi_height_hint )
182 {
183     return p_intf->p_sys->p_video_window->GetWindow( p_vout,
184                                                      pi_x_hint, pi_y_hint,
185                                                      pi_width_hint,
186                                                      pi_height_hint );
187 }
188
189 /* Part of the hack to get the X11 window handle from the GtkWidget */
190 #ifdef __WXGTK__
191 extern "C" {
192 #ifdef __WXGTK20__
193     int gdk_x11_drawable_get_xid( void * );
194 #endif
195     void *gtk_widget_get_parent_window( void * );
196 }
197 #endif
198
199 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
200                               int *pi_x_hint, int *pi_y_hint,
201                               unsigned int *pi_width_hint,
202                               unsigned int *pi_height_hint )
203 {
204 #if defined(__WXGTK__) || defined(WIN32)
205     vlc_mutex_lock( &lock );
206
207     if( p_vout )
208     {
209         vlc_mutex_unlock( &lock );
210         msg_Dbg( p_intf, "Video window already in use" );
211         return NULL;
212     }
213
214     p_vout = _p_vout;
215
216     wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
217                        UpdateSize_Event );
218     AddPendingEvent( event );
219     vlc_mutex_unlock( &lock );
220
221 #ifdef __WXGTK__
222     GtkWidget *p_widget = p_child_window->GetHandle();
223
224 #ifdef __WXGTK20__
225     return (void *)gdk_x11_drawable_get_xid(
226                gtk_widget_get_parent_window( p_widget ) );
227 #elif defined(__WXGTK__)
228     return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
229                + 2 * sizeof(void *) );
230 #endif
231
232 #elif defined(WIN32)
233     return (void*)GetHandle();
234
235 #endif
236
237 #else // defined(__WXGTK__) || defined(WIN32)
238     return NULL;
239
240 #endif
241 }
242
243 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
244 {
245     return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
246 }
247
248 void VideoWindow::ReleaseWindow( void *p_window )
249 {
250     vlc_mutex_lock( &lock );
251     p_vout = NULL;
252     vlc_mutex_unlock( &lock );
253
254     if( !b_auto_size ) return;
255
256 #if defined(__WXGTK__) || defined(WIN32)
257     wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
258     AddPendingEvent( event );
259 #endif
260 }
261
262 void VideoWindow::UpdateSize( wxEvent &_event )
263 {
264     m_hide_timer.Stop();
265
266     if( !b_auto_size ) return;
267
268     wxSizeEvent * event = (wxSizeEvent*)(&_event);
269     if( !b_shown )
270     {
271         p_intf->p_sys->p_video_sizer->Show( this, TRUE );
272         p_intf->p_sys->p_video_sizer->Layout();
273         SetFocus();
274         b_shown = VLC_TRUE;
275     }
276
277     p_intf->p_sys->p_video_sizer->SetMinSize( event->GetSize() );
278
279     i_creation_date = mdate();
280     wxCommandEvent intf_event( wxEVT_INTF, 0 );
281     p_parent->AddPendingEvent( intf_event );
282 }
283
284 void VideoWindow::UpdateHide( wxEvent &_event )
285 {
286     if( b_auto_size ) m_hide_timer.Start( 200, wxTIMER_ONE_SHOT );
287 }
288
289 void VideoWindow::OnHideTimer( wxTimerEvent& WXUNUSED(event))
290 {
291     if( b_shown )
292     {
293         p_intf->p_sys->p_video_sizer->Show( this, FALSE );
294         SetSize( 0, 0 );
295         p_intf->p_sys->p_video_sizer->Layout();
296         b_shown = VLC_FALSE;
297     }
298     p_intf->p_sys->p_video_sizer->SetMinSize( wxSize(0,0) );
299
300     wxCommandEvent intf_event( wxEVT_INTF, 0 );
301     p_parent->AddPendingEvent( intf_event );
302 }
303
304 void VideoWindow::OnControlEvent( wxCommandEvent &event )
305 {
306     switch( event.GetId() )
307     {
308     case SetStayOnTop_Event:
309         wxCommandEvent intf_event( wxEVT_INTF, 1 );
310         intf_event.SetInt( event.GetInt() );
311         p_parent->AddPendingEvent( intf_event );
312         break;
313     }
314 }
315
316 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
317                           int i_query, va_list args )
318 {
319     return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
320                                                          args );
321 }
322
323 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
324 {
325     int i_ret = VLC_EGENERIC;
326
327     vlc_mutex_lock( &lock );
328
329     switch( i_query )
330     {
331         case VOUT_GET_SIZE:
332         {
333             unsigned int *pi_width  = va_arg( args, unsigned int * );
334             unsigned int *pi_height = va_arg( args, unsigned int * );
335
336             *pi_width = GetSize().GetWidth();
337             *pi_height = GetSize().GetHeight();
338             i_ret = VLC_SUCCESS;
339         }
340         break;
341
342         case VOUT_SET_SIZE:
343         {
344             if( !b_auto_size ) break;
345
346             unsigned int i_width  = va_arg( args, unsigned int );
347             unsigned int i_height = va_arg( args, unsigned int );
348
349             vlc_mutex_lock( &lock );
350             if( !i_width && p_vout ) i_width = p_vout->i_window_width;
351             if( !i_height && p_vout ) i_height = p_vout->i_window_height;
352             vlc_mutex_unlock( &lock );
353
354             /* Update dimensions */
355             wxSizeEvent event( wxSize( i_width, i_height ), UpdateSize_Event );
356
357             AddPendingEvent( event );
358
359             i_ret = VLC_SUCCESS;
360         }
361         break;
362
363         case VOUT_SET_STAY_ON_TOP:
364         {
365             int i_arg = va_arg( args, int );
366             wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
367             event.SetInt( i_arg );
368             AddPendingEvent( event );
369
370             i_ret = VLC_SUCCESS;
371         }
372         break;
373
374         default:
375             msg_Dbg( p_intf, "control query not supported" );
376             break;
377     }
378
379     vlc_mutex_unlock( &lock );
380
381     return i_ret;
382 }