* modules/gui/skins/*: compilation fixes for MSVC. Almost working, we just to find...
[vlc.git] / modules / gui / skins / win32 / win32_run.cpp
1 /*****************************************************************************
2  * win32_run.cpp:
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: win32_run.cpp,v 1.14 2003/05/02 15:53:32 gbazin Exp $
6  *
7  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8  *          Emmanuel Puig    <karibu@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,
23  * USA.
24  *****************************************************************************/
25
26 #ifdef WIN32
27
28 //--- VLC -------------------------------------------------------------------
29 #include <vlc/vlc.h>
30 #include <vlc/intf.h>
31
32 //--- GENERAL ---------------------------------------------------------------
33 #ifndef BASIC_SKINS
34 #include <wx/wx.h>
35 #endif
36 #include <windows.h>
37
38 //--- SKIN ------------------------------------------------------------------
39 #include "../os_api.h"
40 #include "../src/event.h"
41 #include "../os_event.h"
42 #include "../src/banks.h"
43 #include "../src/window.h"
44 #include "../os_window.h"
45 #include "../src/theme.h"
46 #include "../os_theme.h"
47 #include "../src/skin_common.h"
48 #include "../src/vlcproc.h"
49
50 #ifndef BASIC_SKINS
51 #include "../src/wxdialogs.h"
52 #include "share/vlc32x32.xpm"       // include the graphic icon
53 #endif
54
55 //---------------------------------------------------------------------------
56 // Specific method
57 //---------------------------------------------------------------------------
58 bool IsVLCEvent( unsigned int msg );
59 int  SkinManage( intf_thread_t *p_intf );
60
61
62 #ifndef BASIC_SKINS
63 //---------------------------------------------------------------------------
64 // Local classes declarations.
65 //---------------------------------------------------------------------------
66 class Instance: public wxApp
67 {
68 public:
69     Instance();
70     Instance( intf_thread_t *_p_intf );
71
72     bool OnInit();
73     int  OnExit();
74     OpenDialog *open;
75
76 private:
77     intf_thread_t *p_intf;
78 };
79
80 class ExitTimer: public wxTimer
81 {
82 public:
83     ExitTimer( intf_thread_t *_p_intf );
84
85     void Notify();
86
87 private:
88     intf_thread_t *p_intf;
89 };
90
91
92 //---------------------------------------------------------------------------
93 // Implementation of Instance class
94 //---------------------------------------------------------------------------
95 Instance::Instance( )
96 {
97 }
98
99 Instance::Instance( intf_thread_t *_p_intf )
100 {
101     // Initialization
102     p_intf = _p_intf;
103 }
104
105 IMPLEMENT_APP_NO_MAIN(Instance)
106
107 bool Instance::OnInit()
108 {
109     p_intf->p_sys->p_icon = new wxIcon( vlc_xpm );
110
111     // Create all the dialog boxes
112     p_intf->p_sys->OpenDlg = new OpenDialog( p_intf, NULL, FILE_ACCESS );
113     p_intf->p_sys->MessagesDlg = new Messages( p_intf, NULL );
114     p_intf->p_sys->SoutDlg = new SoutDialog( p_intf, NULL );
115     p_intf->p_sys->PrefsDlg = new PrefsDialog( p_intf, NULL );
116     p_intf->p_sys->InfoDlg = new FileInfo( p_intf, NULL );
117
118     // Start a timer checking if we must exit the main loop
119     p_intf->p_sys->b_wx_die = 0;
120     p_intf->p_sys->p_kludgy_timer = new ExitTimer( p_intf );
121     p_intf->p_sys->p_kludgy_timer->Start( 100 );
122
123     // OK, initialization is over, now the other thread can go on working...
124     vlc_mutex_lock( &p_intf->p_sys->init_lock );
125     vlc_cond_signal( &p_intf->p_sys->init_cond );
126     vlc_mutex_unlock( &p_intf->p_sys->init_lock );
127
128     return TRUE;
129 }
130
131 int Instance::OnExit()
132 {
133     // Delete evertything
134     delete p_intf->p_sys->p_kludgy_timer;
135     delete p_intf->p_sys->InfoDlg;
136     delete p_intf->p_sys->PrefsDlg;
137     delete p_intf->p_sys->SoutDlg;
138     delete p_intf->p_sys->MessagesDlg;
139     delete p_intf->p_sys->OpenDlg;
140     delete p_intf->p_sys->p_icon;
141
142     return 0;
143 }
144
145
146 //---------------------------------------------------------------------------
147 // Implementation of ExitTimer class
148 // This timer is only there to call wxApp::ExitMainLoop() from the wxWindows
149 // thread (otherwise we never exit from the wxEntry call).
150 //---------------------------------------------------------------------------
151 ExitTimer::ExitTimer( intf_thread_t *_p_intf ) : wxTimer()
152 {
153     p_intf = _p_intf;
154 }
155
156 void ExitTimer::Notify()
157 {
158     if( p_intf->p_sys->b_wx_die )
159         wxTheApp->ExitMainLoop();
160 }
161
162
163 //---------------------------------------------------------------------------
164 #if !defined(__BUILTIN__) && defined( WIN32 )
165 HINSTANCE hInstance = 0;
166 extern "C" BOOL WINAPI
167 DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
168 {
169     hInstance = (HINSTANCE)hModule;
170     return TRUE;
171 }
172 #endif
173
174
175 //---------------------------------------------------------------------------
176 // Thread callback
177 // We create all wxWindows dialogs in a separate thread because we don't want
178 // any interaction with our own message loop
179 //---------------------------------------------------------------------------
180 void SkinsDialogsThread( intf_thread_t *p_intf )
181 {
182     /* Hack to pass the p_intf pointer to the new wxWindow Instance object */
183     wxTheApp = new Instance( p_intf );
184
185 #if defined( WIN32 )
186 #if !defined(__BUILTIN__)
187     wxEntry( hInstance/*GetModuleHandle(NULL)*/, NULL, NULL, SW_SHOW, TRUE );
188 #else
189     wxEntry( GetModuleHandle( NULL ), NULL, NULL, SW_SHOW, TRUE );
190 #endif
191 #else
192     wxEntry( 1, p_args );
193 #endif
194
195     return;
196 }
197
198 #endif // WX_SKINS
199
200 //---------------------------------------------------------------------------
201 // Refresh Timer Callback
202 //---------------------------------------------------------------------------
203 void CALLBACK RefreshTimer( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime )
204 {
205     intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd,
206         GWLP_USERDATA );
207     SkinManage( p_intf );
208 }
209 //---------------------------------------------------------------------------
210
211
212
213 //---------------------------------------------------------------------------
214 // Win32 interface
215 //---------------------------------------------------------------------------
216 void OSRun( intf_thread_t *p_intf )
217 {
218     VlcProc *Proc = new VlcProc( p_intf );
219     MSG msg;
220     list<SkinWindow *>::const_iterator win;
221     Event *ProcessEvent;
222     int KeyModifier = 0;
223
224 #ifndef BASIC_SKINS
225     // Create a new thread for wxWindows
226     if( vlc_thread_create( p_intf, "Skins Dialogs Thread", SkinsDialogsThread,
227                            0, 0 ) )
228     {
229         msg_Err( p_intf, "cannot create SkinsDialogsThread" );
230         // Don't even enter the main loop
231         return;
232     }
233     vlc_mutex_lock( &p_intf->p_sys->init_lock );
234     vlc_cond_wait( &p_intf->p_sys->init_cond, &p_intf->p_sys->init_lock );
235     vlc_mutex_unlock( &p_intf->p_sys->init_lock );
236 #endif
237
238      // Create refresh timer
239     SetTimer( ((OSTheme *)p_intf->p_sys->p_theme)->GetParentWindow(), 42, 200,
240               (TIMERPROC)RefreshTimer );
241
242     // Compute windows message list
243     while( GetMessage( &msg, NULL, 0, 0 ) )
244     {
245
246         for( win = p_intf->p_sys->p_theme->WindowList.begin();
247              win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
248         {
249             if( msg.hwnd == NULL ||
250                 msg.hwnd == ((Win32Window*)(*win))->GetHandle() )
251             {
252                 break;
253             }
254         }
255         if( win == p_intf->p_sys->p_theme->WindowList.end() )
256         {
257 //            DispatchMessage( &msg );
258 //            DefWindowProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
259         }
260
261         // Translate keys
262         TranslateMessage( &msg );
263
264         // Create event
265         ProcessEvent = (Event *)new OSEvent( p_intf, msg.hwnd, msg.message,
266                                              msg.wParam, msg.lParam );
267
268         /*****************************
269         * Process keyboard shortcuts *
270         *****************************/
271         if( msg.message == WM_KEYUP )
272         {
273             msg_Err( p_intf, "Key : %i (%i)", msg.wParam, KeyModifier );
274             // If key is CTRL
275             if( msg.wParam == 17 )
276                 KeyModifier = 0;
277             else if( KeyModifier == 0 )
278             {
279                 p_intf->p_sys->p_theme->EvtBank->TestShortcut(
280                     msg.wParam, 0 );
281             }
282         }
283         else if( msg.message == WM_KEYDOWN )
284         {
285             // If key is control
286             if( msg.wParam == 17 )
287                 KeyModifier = 2;
288             else if( KeyModifier > 0 )
289             {
290                 p_intf->p_sys->p_theme->EvtBank->TestShortcut(
291                     msg.wParam, KeyModifier );
292             }
293         }
294         else if( msg.message == WM_SYSKEYDOWN )
295         {
296             // If key is ALT
297             if( msg.wParam == 18 )
298                 KeyModifier = 1;
299         }
300         else if( msg.message == WM_SYSKEYUP )
301         {
302             // If key is a system key
303             KeyModifier = 0;
304         }
305
306         /************************
307         * Process timer message *
308         ************************/
309         else if( msg.message == WM_TIMER )
310         {
311             DispatchMessage( &msg );
312         }
313
314         /***********************
315         * VLC specific message *
316         ***********************/
317         else if( IsVLCEvent( msg.message ) )
318         {
319             if( !Proc->EventProc( ProcessEvent ) )
320                 break;      // Exit VLC !
321         }
322
323         /**********************
324         * Broadcasted message *
325         **********************/
326         else if( msg.hwnd == NULL )
327         {
328             for( win = p_intf->p_sys->p_theme->WindowList.begin();
329                  win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
330             {
331                 (*win)->ProcessEvent( ProcessEvent );
332             }
333         }
334
335         /***********************
336         * Process window event *
337         ***********************/
338         else
339         {
340             DispatchMessage( &msg );
341         }
342
343         // Delete event
344         ProcessEvent->DestructParameters();
345         delete (OSEvent *)ProcessEvent;
346
347         // Check if vlc is closing
348         Proc->IsClosing();
349     }
350
351 #ifndef BASIC_SKINS
352     // Tell wxWindows it's time to exit
353     p_intf->p_sys->b_wx_die = 1;
354 #endif
355 }
356 //---------------------------------------------------------------------------
357 bool IsVLCEvent( unsigned int msg )
358 {
359     return( msg > VLC_MESSAGE && msg < VLC_WINDOW );
360 }
361 //---------------------------------------------------------------------------
362
363 #endif