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