]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/wxwindows.cpp
* src/input/input_clock.c: reverted the patch that caused the regression in 0.6.1
[vlc] / modules / gui / wxwindows / wxwindows.cpp
1 /*****************************************************************************
2  * wxwindows.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id: wxwindows.cpp,v 1.29 2003/08/08 16:50:27 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
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 <stdlib.h>                                      /* malloc(), free() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31
32 #include <vlc/vlc.h>
33
34 #ifdef WIN32                                                 /* mingw32 hack */
35 #undef Yield
36 #undef CreateDialog
37 #endif
38
39 /* Let vlc take care of the i18n stuff */
40 #define WXINTL_NO_GETTEXT_MACRO
41
42 #include <wx/wxprec.h>
43 #include <wx/wx.h>
44
45 #include <vlc/intf.h>
46
47 #include "wxwindows.h"
48
49 /* Temporary hack */
50 #if defined(WIN32) && defined(_WX_INIT_H_)
51 /* Hack to detect wxWindows 2.5 which has a different wxEntry() prototype */
52 extern int wxEntry( HINSTANCE hInstance, HINSTANCE hPrevInstance = NULL,
53                     char *pCmdLine = NULL, int nCmdShow = SW_NORMAL );
54 #endif
55 #ifdef __DARWIN__
56 int wxEntry( int argc, char *argv[] , bool enterLoop = TRUE );
57 #endif
58
59 /*****************************************************************************
60  * Local prototypes.
61  *****************************************************************************/
62 static int  Open         ( vlc_object_t * );
63 static void Close        ( vlc_object_t * );
64 static int  OpenDialogs  ( vlc_object_t * );
65
66 static void Run          ( intf_thread_t * );
67 static void Init         ( intf_thread_t * );
68
69 static void ShowDialog   ( intf_thread_t *, int, int, intf_dialog_args_t * );
70
71 /*****************************************************************************
72  * Local classes declarations.
73  *****************************************************************************/
74 class Instance: public wxApp
75 {
76 public:
77     Instance();
78     Instance( intf_thread_t *_p_intf );
79
80     bool OnInit();
81
82 private:
83     intf_thread_t *p_intf;
84     wxLocale locale;                                /* locale we'll be using */
85 };
86
87 /*****************************************************************************
88  * Module descriptor
89  *****************************************************************************/
90 vlc_module_begin();
91 #ifdef WIN32
92     int i_score = 150;
93 #else
94     int i_score = getenv( "DISPLAY" ) == NULL ? 15 : 150;
95 #endif
96     set_description( (char *) _("wxWindows interface module") );
97     set_capability( "interface", i_score );
98     set_callbacks( Open, Close );
99     add_shortcut( "wxwindows" );
100     add_shortcut( "wxwin" );
101     add_shortcut( "wx" );
102     set_program( "wxvlc" );
103
104     add_submodule();
105     set_description( _("wxWindows dialogs provider") );
106     set_capability( "dialogs provider", 50 );
107     set_callbacks( OpenDialogs, Close );
108
109 #if !defined(WIN32)
110     linked_with_a_crap_library_which_uses_atexit();
111 #endif
112 vlc_module_end();
113
114 /*****************************************************************************
115  * Open: initialize and create window
116  *****************************************************************************/
117 static int Open( vlc_object_t *p_this )
118 {
119     intf_thread_t *p_intf = (intf_thread_t *)p_this;
120
121     /* Allocate instance and initialize some members */
122     p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
123     if( p_intf->p_sys == NULL )
124     {
125         msg_Err( p_intf, "out of memory" );
126         return VLC_ENOMEM;
127     }
128
129     p_intf->pf_run = Run;
130
131     p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
132
133     /* Initialize wxWindows thread */
134     p_intf->p_sys->b_playing = 0;
135
136     p_intf->p_sys->p_input = NULL;
137     p_intf->p_sys->i_playing = -1;
138     p_intf->p_sys->b_slider_free = 1;
139     p_intf->p_sys->i_slider_pos = p_intf->p_sys->i_slider_oldpos = 0;
140
141     p_intf->p_sys->p_popup_menu = NULL;
142
143     p_intf->pf_show_dialog = NULL;
144
145     return VLC_SUCCESS;
146 }
147
148 static int OpenDialogs( vlc_object_t *p_this )
149 {
150     intf_thread_t *p_intf = (intf_thread_t *)p_this;
151     int i_ret = Open( p_this );
152
153     p_intf->pf_show_dialog = ShowDialog;
154
155     return i_ret;
156 }
157
158 /*****************************************************************************
159  * Close: destroy interface window
160  *****************************************************************************/
161 static void Close( vlc_object_t *p_this )
162 {
163     intf_thread_t *p_intf = (intf_thread_t *)p_this;
164
165     if( p_intf->p_sys->p_input )
166     {
167         vlc_object_release( p_intf->p_sys->p_input );
168     }
169
170     if( p_intf->pf_show_dialog )
171     {
172         /* We must destroy the dialogs thread */
173         wxCommandEvent event( wxEVT_DIALOG, INTF_DIALOG_EXIT );
174         p_intf->p_sys->p_wxwindow->AddPendingEvent( event );
175         vlc_thread_join( p_intf );
176     }
177
178     msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
179
180     /* Destroy structure */
181     free( p_intf->p_sys );
182 }
183
184 /*****************************************************************************
185  * Run: wxWindows thread
186  *****************************************************************************/
187 #if !defined(__BUILTIN__) && defined( WIN32 )
188 HINSTANCE hInstance = 0;
189 extern "C" BOOL WINAPI
190 DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
191 {
192     hInstance = (HINSTANCE)hModule;
193     return TRUE;
194 }
195 #endif
196
197 static void Run( intf_thread_t *p_intf )
198 {
199     if( p_intf->pf_show_dialog )
200     {
201         /* The module is used in dialog provider mode */
202
203         /* Create a new thread for wxWindows */
204         if( vlc_thread_create( p_intf, "Skins Dialogs Thread",
205                                Init, 0, VLC_TRUE ) )
206         {
207             msg_Err( p_intf, "cannot create Skins Dialogs Thread" );
208             p_intf->pf_show_dialog = NULL;
209         }
210     }
211     else
212     {
213         /* The module is used in interface mode */
214         Init( p_intf );
215     }
216 }
217
218 static void Init( intf_thread_t *p_intf )
219 {
220 #if !defined( WIN32 )
221     static char  *p_args[] = { "" };
222     int i_args = 1;
223 #endif
224
225     /* Hack to pass the p_intf pointer to the new wxWindow Instance object */
226 #ifdef wxTheApp
227     wxApp::SetInstance( new Instance( p_intf ) );
228 #else
229     wxTheApp = new Instance( p_intf );
230 #endif
231
232 #if defined( WIN32 )
233 #if !defined(__BUILTIN__)
234     wxEntry( hInstance/*GetModuleHandle(NULL)*/, NULL, NULL, SW_SHOW );
235 #else
236     wxEntry( GetModuleHandle(NULL), NULL, NULL, SW_SHOW );
237 #endif
238 #else
239     wxEntry( i_args, p_args );
240 #endif
241
242     if( p_intf->pf_show_dialog )
243     {
244         /* We need to manually clean up the dialogs class */
245         if( p_intf->p_sys->p_wxwindow ) delete p_intf->p_sys->p_wxwindow;
246     }
247 }
248
249 /* following functions are local */
250
251 /*****************************************************************************
252  * Constructors.
253  *****************************************************************************/
254 Instance::Instance( )
255 {
256 }
257
258 Instance::Instance( intf_thread_t *_p_intf )
259 {
260     /* Initialization */
261     p_intf = _p_intf;
262 }
263
264 IMPLEMENT_APP_NO_MAIN(Instance)
265
266 /*****************************************************************************
267  * Instance::OnInit: the parent interface execution starts here
268  *****************************************************************************
269  * This is the "main program" equivalent, the program execution will
270  * start here.
271  *****************************************************************************/
272 bool Instance::OnInit()
273 {
274     /* Initialization of i18n stuff.
275      * Usefull for things we don't have any control over, like wxWindows
276      * provided facilities (eg. open file dialog) */
277     locale.Init( wxLANGUAGE_DEFAULT );
278
279     /* Make an instance of your derived frame. Passing NULL (the default value
280      * of Frame's constructor is NULL) as the frame doesn't have a parent
281      * since it is the first window */
282
283     if( !p_intf->pf_show_dialog )
284     {
285         /* The module is used in interface mode */
286         Interface *MainInterface = new Interface( p_intf );
287         p_intf->p_sys->p_wxwindow = MainInterface;
288
289         /* Show the interface */
290         MainInterface->Show( TRUE );
291
292         SetTopWindow( MainInterface );
293
294         /* Start timer */
295         new Timer( p_intf, MainInterface );
296     }
297
298     /* Creates the dialogs provider */
299     p_intf->p_sys->p_wxwindow =
300         new DialogsProvider( p_intf, p_intf->pf_show_dialog ?
301                              NULL : p_intf->p_sys->p_wxwindow );
302
303     p_intf->p_sys->pf_show_dialog = ShowDialog;
304
305     /* OK, initialization is over */
306     vlc_thread_ready( p_intf );
307
308     /* Return TRUE to tell program to continue (FALSE would terminate) */
309     return TRUE;
310 }
311
312 static void ShowDialog( intf_thread_t *p_intf, int i_dialog_event, int i_arg,
313                         intf_dialog_args_t *p_arg )
314 {
315     wxCommandEvent event( wxEVT_DIALOG, i_dialog_event );
316     event.SetInt( i_arg );
317     event.SetClientData( p_arg );
318
319     /* Hack to prevent popup events to be enqueued when
320      * one is already active */
321     if( i_dialog_event != INTF_DIALOG_POPUPMENU ||
322         !p_intf->p_sys->p_popup_menu )
323     {
324         p_intf->p_sys->p_wxwindow->AddPendingEvent( event );
325     }
326 }