]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/video.cpp
include services discovery in interface
[vlc] / modules / gui / wxwindows / video.cpp
1 /*****************************************************************************
2  * video.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004, 2003 VideoLAN
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 "wxwindows.h"
32
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 );
37
38 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window );
39
40 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
41                           int i_query, va_list args );
42
43 /* IDs for the controls and the menu commands */
44 enum
45 {
46     UpdateSize_Event = wxID_HIGHEST + 1,
47     UpdateHide_Event,
48     SetStayOnTop_Event,
49 };
50
51 class VideoWindow: public wxWindow
52 {
53 public:
54     /* Constructor */
55     VideoWindow( intf_thread_t *_p_intf, wxWindow *p_parent );
56     virtual ~VideoWindow();
57
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 );
62
63 private:
64     intf_thread_t *p_intf;
65     vout_thread_t *p_vout;
66     wxWindow *p_parent;
67     vlc_mutex_t lock;
68     vlc_bool_t b_shown;
69
70     wxWindow *p_child_window;
71
72     void UpdateSize( wxSizeEvent & );
73     void UpdateHide( wxSizeEvent & );
74     void OnControlEvent( wxCommandEvent & );
75
76     DECLARE_EVENT_TABLE();
77 };
78
79 DEFINE_LOCAL_EVENT_TYPE( wxEVT_VLC_VIDEO );
80
81 BEGIN_EVENT_TABLE(VideoWindow, wxWindow)
82     EVT_CUSTOM( wxEVT_SIZE, UpdateSize_Event, VideoWindow::UpdateSize )
83     EVT_CUSTOM( wxEVT_SIZE, UpdateHide_Event, VideoWindow::UpdateHide )
84     EVT_COMMAND( SetStayOnTop_Event, wxEVT_VLC_VIDEO,
85                  VideoWindow::OnControlEvent )
86 END_EVENT_TABLE()
87
88 /*****************************************************************************
89  * Public methods.
90  *****************************************************************************/
91 wxWindow *VideoWindow( intf_thread_t *p_intf, wxWindow *p_parent )
92 {
93     return new VideoWindow::VideoWindow( p_intf, p_parent );
94 }
95
96 /*****************************************************************************
97  * Constructor.
98  *****************************************************************************/
99 VideoWindow::VideoWindow( intf_thread_t *_p_intf, wxWindow *_p_parent ):
100     wxWindow( _p_parent, -1 )
101 {
102     /* Initializations */
103     p_intf = _p_intf;
104     p_parent = _p_parent;
105
106     vlc_mutex_init( p_intf, &lock );
107
108     p_vout = NULL;
109
110     p_intf->pf_request_window = ::GetWindow;
111     p_intf->pf_release_window = ::ReleaseWindow;
112     p_intf->pf_control_window = ::ControlWindow;
113
114     p_intf->p_sys->p_video_window = this;
115     p_child_window = new wxWindow( this, -1, wxDefaultPosition, wxSize(0,0) );
116     p_child_window->Show();
117     Show();
118     b_shown = VLC_TRUE;
119
120     p_intf->p_sys->p_video_sizer = new wxBoxSizer( wxHORIZONTAL );
121     p_intf->p_sys->p_video_sizer->Add( this, 1, wxEXPAND );
122
123     ReleaseWindow( NULL );
124 }
125
126 VideoWindow::~VideoWindow()
127 {
128     vlc_mutex_lock( &lock );
129     if( p_vout )
130     {
131         if( !p_intf->psz_switch_intf )
132         {
133             if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
134                 vout_Control( p_vout, VOUT_REPARENT );
135         }
136         else
137         {
138             if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
139                 vout_Control( p_vout, VOUT_CLOSE );
140         }
141     }
142
143     p_intf->pf_request_window = NULL;
144     p_intf->pf_release_window = NULL;
145     p_intf->pf_control_window = NULL;
146     vlc_mutex_unlock( &lock );
147
148     vlc_mutex_destroy( &lock );
149 }
150
151 /*****************************************************************************
152  * Private methods.
153  *****************************************************************************/
154 static void *GetWindow( intf_thread_t *p_intf, vout_thread_t *p_vout,
155                         int *pi_x_hint, int *pi_y_hint,
156                         unsigned int *pi_width_hint,
157                         unsigned int *pi_height_hint )
158 {
159     return p_intf->p_sys->p_video_window->GetWindow( p_vout,
160                                                      pi_x_hint, pi_y_hint,
161                                                      pi_width_hint,
162                                                      pi_height_hint );
163 }
164
165 /* Part of the hack to get the X11 window handle from the GtkWidget */
166 #ifdef __WXGTK__
167 extern "C" {
168 #ifdef __WXGTK20__
169     int gdk_x11_drawable_get_xid( void * );
170 #endif
171     void *gtk_widget_get_parent_window( void * );
172 }
173 #endif
174
175 void *VideoWindow::GetWindow( vout_thread_t *_p_vout,
176                               int *pi_x_hint, int *pi_y_hint,
177                               unsigned int *pi_width_hint,
178                               unsigned int *pi_height_hint )
179 {
180 #if defined(__WXGTK__) || defined(WIN32)
181     vlc_mutex_lock( &lock );
182
183     if( p_vout )
184     {
185         vlc_mutex_unlock( &lock );
186         msg_Dbg( p_intf, "Video window already in use" );
187         return NULL;
188     }
189
190     p_vout = _p_vout;
191
192     wxSizeEvent event( wxSize(*pi_width_hint, *pi_height_hint),
193                        UpdateSize_Event );
194     AddPendingEvent( event );
195     vlc_mutex_unlock( &lock );
196
197 #ifdef __WXGTK__
198     GtkWidget *p_widget = p_child_window->GetHandle();
199
200 #ifdef __WXGTK20__
201     return (void *)gdk_x11_drawable_get_xid(
202                gtk_widget_get_parent_window( p_widget ) );
203 #elif defined(__WXGTK__)
204     return (void *)*(int *)( (char *)gtk_widget_get_parent_window( p_widget )
205                + 2 * sizeof(void *) );
206 #endif
207
208 #elif defined(WIN32)
209     return (void*)GetHandle();
210
211 #endif
212
213 #else // defined(__WXGTK__) || defined(WIN32)
214     return NULL;
215
216 #endif
217 }
218
219 static void ReleaseWindow( intf_thread_t *p_intf, void *p_window )
220 {
221     return p_intf->p_sys->p_video_window->ReleaseWindow( p_window );
222 }
223
224 void VideoWindow::ReleaseWindow( void *p_window )
225 {
226     vlc_mutex_lock( &lock );
227
228     p_vout = NULL;
229
230 #if defined(__WXGTK__) || defined(WIN32)
231     wxSizeEvent event( wxSize(0, 0), UpdateHide_Event );
232     AddPendingEvent( event );
233 #endif
234
235     vlc_mutex_unlock( &lock );
236 }
237
238 void VideoWindow::UpdateSize( wxSizeEvent &event )
239 {
240     if( !b_shown )
241     {
242         p_intf->p_sys->p_video_sizer->Show( this, TRUE );
243         p_intf->p_sys->p_video_sizer->Layout();
244         SetFocus();
245         b_shown = VLC_TRUE;
246     }
247     p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
248
249     wxCommandEvent intf_event( wxEVT_INTF, 0 );
250     p_parent->AddPendingEvent( intf_event );
251 }
252
253 void VideoWindow::UpdateHide( wxSizeEvent &event )
254 {
255     if( b_shown )
256     {
257         p_intf->p_sys->p_video_sizer->Show( this, FALSE );
258         p_intf->p_sys->p_video_sizer->Layout();
259         b_shown = VLC_FALSE;
260
261         SetSize(0,0);
262         Show();
263     }
264     p_intf->p_sys->p_video_sizer->SetMinSize( event.GetSize() );
265
266     wxCommandEvent intf_event( wxEVT_INTF, 0 );
267     p_parent->AddPendingEvent( intf_event );
268 }
269
270 void VideoWindow::OnControlEvent( wxCommandEvent &event )
271 {
272     switch( event.GetId() )
273     {
274     case SetStayOnTop_Event:
275         wxCommandEvent intf_event( wxEVT_INTF, 1 );
276         intf_event.SetInt( event.GetInt() );
277         p_parent->AddPendingEvent( intf_event );
278         break;
279     }
280 }
281
282 static int ControlWindow( intf_thread_t *p_intf, void *p_window,
283                           int i_query, va_list args )
284 {
285     return p_intf->p_sys->p_video_window->ControlWindow( p_window, i_query,
286                                                          args );
287 }
288
289 int VideoWindow::ControlWindow( void *p_window, int i_query, va_list args )
290 {
291     int i_ret = VLC_EGENERIC;
292
293     vlc_mutex_lock( &lock );
294
295     switch( i_query )
296     {
297         case VOUT_SET_ZOOM:
298         {
299             double f_arg = va_arg( args, double );
300
301             /* Update dimensions */
302             wxSizeEvent event( wxSize((int)(p_vout->i_window_width * f_arg),
303                                       (int)(p_vout->i_window_height * f_arg)),
304                                UpdateSize_Event );
305             AddPendingEvent( event );
306
307             i_ret = VLC_SUCCESS;
308         }
309         break;
310
311         case VOUT_SET_STAY_ON_TOP:
312         {
313             int i_arg = va_arg( args, int );
314             wxCommandEvent event( wxEVT_VLC_VIDEO, SetStayOnTop_Event );
315             event.SetInt( i_arg );
316             AddPendingEvent( event );
317
318             i_ret = VLC_SUCCESS;
319         }
320         break;
321
322         default:
323             msg_Dbg( p_intf, "control query not supported" );
324             break;
325     }
326
327     vlc_mutex_unlock( &lock );
328
329     return i_ret;
330 }