]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/video.cpp
psz_intf_switch was read-only: remove dead code
[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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_vout.h>
33 #include <vlc_interface.h>
34
35 #include "video.hpp"
36 #include "interface.hpp"
37
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 );
42
43 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
44
45 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
46                           int i_query, va_list args );
47
48 /* IDs for the controls and the menu commands */
49 enum
50 {
51     UpdateSize_Event = wxID_HIGHEST + 1,
52     UpdateHide_Event,
53     SetStayOnTop_Event,
54     ID_HIDE_TIMER
55 };
56
57 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
58
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 )
65 END_EVENT_TABLE()
66
67 /*****************************************************************************
68  * Public methods.
69  *****************************************************************************/
70 wxWindow *CreateVideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
71 {
72     return new VideoWindow( p_intf, p_parent );
73 }
74
75 void UpdateVideoWindow( intf_thread_t *p_intf, wxWindow *p_window )
76 {
77 #if wxCHECK_VERSION(2,5,3)
78     if( !p_intf->p_sys->b_video_autosize ) return;
79
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 :( */
83
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() );
86 #endif
87 }
88
89 /*****************************************************************************
90  * Constructor.
91  *****************************************************************************/
92 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
93   wxWindow( _p_parent, -1, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN )
94 {
95     /* Initializations */
96     p_intf = _p_intf;
97     p_parent = _p_parent;
98     p_child_window = 0;
99
100     vlc_mutex_init( &lock );
101
102     b_auto_size = p_intf->p_sys->b_video_autosize;
103
104     p_vout = NULL;
105     i_creation_date = 0;
106     m_hide_timer.SetOwner( this, ID_HIDE_TIMER );
107
108     p_intf->pf_request_window = ::GetWindow;
109     p_intf->pf_release_window = ::ReleaseWindow;
110     p_intf->pf_control_window = ::ControlWindow;
111
112     p_intf->p_sys->p_video_window = this;
113
114     wxSize child_size = wxSize(0,0);
115     if( !b_auto_size )
116     {
117         WindowSettings *ws = p_intf->p_sys->p_window_settings;
118         wxPoint p; bool b_shown;
119
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 );
123
124         ws->GetSettings( WindowSettings::ID_VIDEO, b_shown, p, child_size );
125         SetSize( child_size );
126     }
127
128 #ifdef __WXGTK__
129     p_child_window = new wxWindow( this, -1, wxDefaultPosition, child_size,
130                                    wxCLIP_CHILDREN );
131 #endif
132
133     if( !b_auto_size )
134     {
135         SetBackgroundColour( *wxBLACK );
136         if( p_child_window ) p_child_window->SetBackgroundColour( *wxBLACK );
137     }
138
139     if( p_child_window ) p_child_window->Show();
140     Show();
141     b_shown = true;
142
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 );
146 #else
147     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
148 #endif
149
150     ReleaseWindow( NULL );
151 }
152
153 VideoWindow::~VideoWindow()
154 {
155     vlc_mutex_lock( &lock );
156     if( p_vout )
157     {
158         if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
159             vout_Control( p_vout, VOUT_REPARENT, 0 );
160     }
161
162     p_intf->pf_request_window = NULL;
163     p_intf->pf_release_window = NULL;
164     p_intf->pf_control_window = NULL;
165     vlc_mutex_unlock( &lock );
166
167     if( !b_auto_size )
168     {
169         WindowSettings *ws = p_intf->p_sys->p_window_settings;
170         ws->SetSettings( WindowSettings::ID_VIDEO, true,
171                          GetPosition(), GetSize() );
172     }
173
174     vlc_mutex_destroy( &lock );
175 }
176
177 /*****************************************************************************
178  * Private methods.
179  *****************************************************************************/
180 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
181                         int *pi_x_hint, int *pi_y_hint,
182                         unsigned int *pi_width_hint,
183                         unsigned int *pi_height_hint )
184 {
185     return p_intf->p_sys->p_video_window->GetWindow( p_vout,
186                                                      pi_x_hint, pi_y_hint,
187                                                      pi_width_hint,
188                                                      pi_height_hint );
189 }
190
191 /* Part of the hack to get the X11 window handle from the GtkWidget */
192 #ifdef __WXGTK__
193 extern "C" {
194 #ifdef __WXGTK20__
195     int gdk_x11_drawable_get_xid( void * );
196 #endif
197     void *gtk_widget_get_parent_window( void * );
198 }
199 #endif
200
201 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
202                               int *pi_x_hint, int *pi_y_hint,
203                               unsigned int *pi_width_hint,
204                               unsigned int *pi_height_hint )
205 {
206 #if defined(__WXGTK__) || defined(WIN32)
207     vlc_mutex_lock( &lock );
208
209     if( p_vout )
210     {
211         vlc_mutex_unlock( &lock );
212         msg_Dbg( p_intf, "video window already in use" );
213         return NULL;
214     }
215
216     p_vout = _p_vout;
217
218     wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
219                        UpdateSize_Event );
220     AddPendingEvent( event );
221     vlc_mutex_unlock( &lock );
222
223 #ifdef __WXGTK__
224     GtkWidget *p_widget = p_child_window->GetHandle();
225
226 #ifdef __WXGTK20__
227     return (void *)gdk_x11_drawable_get_xid(
228                gtk_widget_get_parent_window( p_widget ) );
229 #elif defined(__WXGTK__)
230     return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
231                + 2 * sizeof(void *) );
232 #endif
233
234 #elif defined(WIN32)
235     return (void*)GetHandle();
236
237 #endif
238
239 #else // defined(__WXGTK__) || defined(WIN32)
240     return NULL;
241
242 #endif
243 }
244
245 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
246 {
247     return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
248 }
249
250 void VideoWindow::ReleaseWindow( void *p_window )
251 {
252     vlc_mutex_lock( &lock );
253     p_vout = NULL;
254     vlc_mutex_unlock( &lock );
255
256     if( !b_auto_size ) return;
257
258 #if defined(__WXGTK__) || defined(WIN32)
259     wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
260     AddPendingEvent( event );
261 #endif
262 }
263
264 void VideoWindow::UpdateSize( wxEvent &_event )
265 {
266     m_hide_timer.Stop();
267
268     if( !b_auto_size ) return;
269
270     wxSizeEvent * event = (wxSizeEvent*)(&_event);
271     if( !b_shown )
272     {
273         p_intf->p_sys->p_video_sizer->Show( this, TRUE );
274         p_intf->p_sys->p_video_sizer->Layout();
275         SetFocus();
276         b_shown = true;
277     }
278
279     p_intf->p_sys->p_video_sizer->SetMinSize( event->GetSize() );
280
281     i_creation_date = mdate();
282     wxCommandEvent intf_event( wxEVT_INTF, 0 );
283     p_parent->AddPendingEvent( intf_event );
284 }
285
286 void VideoWindow::UpdateHide( wxEvent &_event )
287 {
288     if( b_auto_size ) m_hide_timer.Start( 200, wxTIMER_ONE_SHOT );
289 }
290
291 void VideoWindow::OnHideTimer( wxTimerEvent& WXUNUSED(event))
292 {
293     if( b_shown )
294     {
295         p_intf->p_sys->p_video_sizer->Show( this, FALSE );
296         SetSize( 0, 0 );
297         p_intf->p_sys->p_video_sizer->Layout();
298         b_shown = false;
299     }
300     p_intf->p_sys->p_video_sizer->SetMinSize( wxSize(0,0) );
301
302     wxCommandEvent intf_event( wxEVT_INTF, 0 );
303     p_parent->AddPendingEvent( intf_event );
304 }
305
306 void VideoWindow::OnControlEvent( wxCommandEvent &event )
307 {
308     switch( event.GetId() )
309     {
310     case SetStayOnTop_Event:
311         wxCommandEvent intf_event( wxEVT_INTF, 1 );
312         intf_event.SetInt( event.GetInt() );
313         p_parent->AddPendingEvent( intf_event );
314         break;
315     }
316 }
317
318 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
319                           int i_query, va_list args )
320 {
321     return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
322                                                          args );
323 }
324
325 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
326 {
327     int i_ret = VLC_EGENERIC;
328
329     vlc_mutex_lock( &lock );
330
331     switch( i_query )
332     {
333         case VOUT_GET_SIZE:
334         {
335             unsigned int *pi_width  = va_arg( args, unsigned int * );
336             unsigned int *pi_height = va_arg( args, unsigned int * );
337
338             *pi_width = GetSize().GetWidth();
339             *pi_height = GetSize().GetHeight();
340             i_ret = VLC_SUCCESS;
341         }
342         break;
343
344         case VOUT_SET_SIZE:
345         {
346             if( !b_auto_size ) break;
347
348             unsigned int i_width  = va_arg( args, unsigned int );
349             unsigned int i_height = va_arg( args, unsigned int );
350
351             if( !i_width && p_vout ) i_width = p_vout->i_window_width;
352             if( !i_height && p_vout ) i_height = p_vout->i_window_height;
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 }