* fixed a timing issue under windows ?
[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.8 2003/04/21 02:50:49 asmax 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 #include <wx/wx.h>
30 #include <windows.h>
31
32 //--- VLC -------------------------------------------------------------------
33 #include <vlc/intf.h>
34
35 //--- SKIN ------------------------------------------------------------------
36 #include "../os_api.h"
37 #include "../src/event.h"
38 #include "../os_event.h"
39 #include "../src/banks.h"
40 #include "../src/window.h"
41 #include "../os_window.h"
42 #include "../src/theme.h"
43 #include "../os_theme.h"
44 #include "../src/skin_common.h"
45 #include "../src/vlcproc.h"
46 #include "../src/wxdialogs.h"
47
48 // include the icon graphic
49 #include "share/vlc32x32.xpm"
50
51 //---------------------------------------------------------------------------
52 // Specific method
53 //---------------------------------------------------------------------------
54 bool IsVLCEvent( unsigned int msg );
55 int  SkinManage( intf_thread_t *p_intf );
56
57
58 //---------------------------------------------------------------------------
59 // Local classes declarations.
60 //---------------------------------------------------------------------------
61 class Instance: public wxApp
62 {
63 public:
64     Instance();
65     Instance( intf_thread_t *_p_intf );
66
67     bool OnInit();
68     OpenDialog *open;
69
70 private:
71     intf_thread_t *p_intf;
72 };
73
74
75 //---------------------------------------------------------------------------
76 // Implementation of Instance class
77 //---------------------------------------------------------------------------
78 Instance::Instance( )
79 {
80 }
81
82 Instance::Instance( intf_thread_t *_p_intf )
83 {
84     // Initialization
85     p_intf = _p_intf;
86 }
87
88 IMPLEMENT_APP_NO_MAIN(Instance)
89
90 bool Instance::OnInit()
91 {
92     p_intf->p_sys->p_icon = new wxIcon( vlc_xpm );
93     p_intf->p_sys->OpenDlg = new OpenDialog( p_intf, NULL, FILE_ACCESS );
94     p_intf->p_sys->MessagesDlg = new Messages( p_intf, NULL );
95     p_intf->p_sys->SoutDlg = new SoutDialog( p_intf, NULL );
96     p_intf->p_sys->PrefsDlg = new PrefsDialog( p_intf, NULL );
97     p_intf->p_sys->InfoDlg = new FileInfo( p_intf, NULL );
98
99     vlc_mutex_lock( &p_intf->p_sys->init_lock );
100     vlc_cond_signal( &p_intf->p_sys->init_cond );
101     vlc_mutex_unlock( &p_intf->p_sys->init_lock );
102     
103     return TRUE;
104 }
105
106
107 //---------------------------------------------------------------------------
108 #if !defined(__BUILTIN__) && defined( WIN32 )
109 HINSTANCE hInstance = 0;
110 extern "C" BOOL WINAPI
111 DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
112 {
113     hInstance = (HINSTANCE)hModule;
114     return TRUE;
115 }
116 #endif
117
118
119 //---------------------------------------------------------------------------
120 // Thread callback
121 // We create all wxWindows dialogs in a separate thread because we don't want
122 // any interaction with our own message loop
123 //---------------------------------------------------------------------------
124 DWORD WINAPI ThreadFunc( LPVOID lpParam )
125 {
126     intf_thread_t *p_intf = (intf_thread_t *)lpParam;
127
128     /* Hack to pass the p_intf pointer to the new wxWindow Instance object */
129     wxTheApp = new Instance( p_intf );
130
131 #if defined( WIN32 )
132 #if !defined(__BUILTIN__)
133     wxEntry( hInstance/*GetModuleHandle(NULL)*/, NULL, NULL, SW_SHOW, TRUE );
134 #else
135     wxEntry( GetModuleHandle( NULL ), NULL, NULL, SW_SHOW, TRUE );
136 #endif
137 #else
138     wxEntry( 1, p_args );
139 #endif
140
141     return 0;
142 }
143
144
145 //---------------------------------------------------------------------------
146 // Refresh Timer Callback
147 //---------------------------------------------------------------------------
148 void CALLBACK RefreshTimer( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime )
149 {
150     intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd,
151         GWLP_USERDATA );
152     SkinManage( p_intf );
153 }
154 //---------------------------------------------------------------------------
155
156
157
158 //---------------------------------------------------------------------------
159 // Win32 interface
160 //---------------------------------------------------------------------------
161 void OSRun( intf_thread_t *p_intf )
162 {
163     VlcProc *Proc = new VlcProc( p_intf );
164     MSG msg;
165     list<Window *>::const_iterator win;
166     Event *ProcessEvent;
167     int KeyModifier = 0;
168
169     // Create a new thread for wxWindows
170     HANDLE hThread;
171     hThread = CreateThread( NULL, 0, ThreadFunc, (LPVOID) p_intf, 0, 0 );
172
173     vlc_mutex_lock( &p_intf->p_sys->init_lock );
174     vlc_cond_wait( &p_intf->p_sys->init_cond, &p_intf->p_sys->init_lock );
175     vlc_mutex_unlock( &p_intf->p_sys->init_lock );
176  
177      // Create refresh timer
178     SetTimer( ((OSTheme *)p_intf->p_sys->p_theme)->GetParentWindow(), 42, 200,
179               (TIMERPROC)RefreshTimer );
180
181     // Compute windows message list
182     while( GetMessage( &msg, NULL, 0, 0 ) )
183     {
184
185         for( win = p_intf->p_sys->p_theme->WindowList.begin();
186             win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
187         {
188             if( msg.hwnd == NULL || msg.hwnd == ((Win32Window*)(*win))->GetHandle() )
189             {
190                 break;
191             }
192         }
193         if( win == p_intf->p_sys->p_theme->WindowList.end() )
194         {
195 //            DispatchMessage( &msg );
196 //            DefWindowProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
197         }
198
199         // Translate keys
200         TranslateMessage( &msg );
201
202         // Create event
203         ProcessEvent = (Event *)new OSEvent( p_intf, msg.hwnd, msg.message,
204                                              msg.wParam, msg.lParam );
205
206         /*****************************
207         * Process keyboard shortcuts *
208         *****************************/
209         if( msg.message == WM_KEYUP )
210         {
211             msg_Err( p_intf, "Key : %i (%i)", msg.wParam, KeyModifier );
212             // If key is CTRL
213             if( msg.wParam == 17 )
214                 KeyModifier = 0;
215             else if( KeyModifier == 0 )
216             {
217                 p_intf->p_sys->p_theme->EvtBank->TestShortcut(
218                     msg.wParam, 0 );
219             }
220         }
221         else if( msg.message == WM_KEYDOWN )
222         {
223             // If key is control
224             if( msg.wParam == 17 )
225                 KeyModifier = 2;
226             else if( KeyModifier > 0 )
227                 p_intf->p_sys->p_theme->EvtBank->TestShortcut(
228                     msg.wParam, KeyModifier );
229         }
230         else if( msg.message == WM_SYSKEYDOWN )
231         {
232             // If key is ALT
233             if( msg.wParam == 18 )
234                 KeyModifier = 1;
235         }
236         else if( msg.message == WM_SYSKEYUP )
237         {
238             // If key is a system key
239             KeyModifier = 0;
240         }
241
242         /************************
243         * Process timer message *
244         ************************/
245         else if( msg.message == WM_TIMER )
246         {
247             DispatchMessage( &msg );
248         }
249
250         /***********************
251         * VLC specific message *
252         ***********************/
253         else if( IsVLCEvent( msg.message ) )
254         {
255             if( !Proc->EventProc( ProcessEvent ) )
256                 break;      // Exit VLC !
257         }
258
259         /**********************
260         * Broadcsated message *
261         **********************/
262         else if( msg.hwnd == NULL )
263         {
264             for( win = p_intf->p_sys->p_theme->WindowList.begin();
265                 win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
266             {
267                 (*win)->ProcessEvent( ProcessEvent );
268             }
269         }
270
271         /***********************
272         * Process window event *
273         ***********************/
274         else
275         {
276             DispatchMessage( &msg );
277         }
278
279         // Delete event
280         ProcessEvent->DestructParameters();
281         delete (OSEvent *)ProcessEvent;
282
283         // Check if vlc is closing
284         Proc->IsClosing();
285     }
286 }
287 //---------------------------------------------------------------------------
288 bool IsVLCEvent( unsigned int msg )
289 {
290     return( msg > VLC_MESSAGE && msg < VLC_WINDOW );
291 }
292 //---------------------------------------------------------------------------
293
294 #endif