* events aren't perfect yet, but it is better enough to commit
[vlc.git] / modules / gui / skins / x11 / x11_run.cpp
1 /*****************************************************************************
2  * x11_run.cpp:
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: x11_run.cpp,v 1.8 2003/05/24 21:28:29 asmax Exp $
6  *
7  * Authors: Cyril Deguet     <asmax@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,
22  * USA.
23  *****************************************************************************/
24
25 #ifdef X11_SKINS
26
27 //--- X11 -------------------------------------------------------------------
28 #include <X11/Xlib.h>
29
30 //--- WWWINDOWS -------------------------------------------------------------
31 #ifndef BASIC_SKINS
32 #include <wx/wx.h>
33 #endif
34
35 //--- VLC -------------------------------------------------------------------
36 #include <vlc/intf.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 #ifndef BASIC_SKINS
50 #include "../../wxwindows/wxwindows.h"
51 #endif
52
53 // include the icon graphic
54 #include "share/vlc32x32.xpm"
55
56 #include <unistd.h>
57
58
59 //---------------------------------------------------------------------------
60 // Specific method
61 //---------------------------------------------------------------------------
62 bool IsVLCEvent( unsigned int msg );
63 int  SkinManage( intf_thread_t *p_intf );
64
65
66 //---------------------------------------------------------------------------
67 // Local classes declarations.
68 //---------------------------------------------------------------------------
69 #ifndef BASIC_SKINS
70 class Instance: public wxApp
71 {
72 public:
73     Instance();
74     Instance( intf_thread_t *_p_intf );
75
76     bool OnInit();
77     OpenDialog *open;
78
79 private:
80     intf_thread_t *p_intf;
81 };
82 #endif
83
84
85 //---------------------------------------------------------------------------
86 // GTK2 interface
87 //---------------------------------------------------------------------------
88 /*void GTK2Proc( GdkEvent *event, gpointer data )
89 {
90     // Get objects from data
91     CallBackObjects *obj = (CallBackObjects *)data;
92     VlcProc *proc        = obj->Proc;
93
94     // Get pointer to thread info
95     intf_thread_t *p_intf = proc->GetpIntf();
96
97     // Variables
98     unsigned int msg;
99     Event *evt;
100     list<SkinWindow *>::const_iterator win;
101     GdkWindow *gwnd = ((GdkEventAny *)event)->window;
102
103     // Create event to dispatch in windows
104     // Skin event
105     if( event->type == GDK_CLIENT_EVENT )
106     {
107         msg = ( (GdkEventClient *)event )->data.l[0];
108         evt = (Event *)new OSEvent( p_intf, 
109             ((GdkEventAny *)event)->window,
110             msg,
111             ( (GdkEventClient *)event )->data.l[1],
112             ( (GdkEventClient *)event )->data.l[2] );
113     }
114     // System event
115     else
116     {
117         msg = event->type;
118         evt = (Event *)new OSEvent( p_intf,
119             ((GdkEventAny *)event)->window, msg, 0, (long)event );
120     }
121
122     // Process keyboard shortcuts
123     if( msg == GDK_KEY_PRESS )
124     {
125         int KeyModifier = 0;
126         // If key is ALT
127         if( ((GdkEventKey *)event)->state & GDK_MOD1_MASK )
128         {
129             KeyModifier = 1;
130         }
131         // If key is CTRL
132         else if( ((GdkEventKey *)event)->state & GDK_CONTROL_MASK )
133         {
134             KeyModifier = 2;
135         }
136         int key = ((GdkEventKey *)event)->keyval;
137         // Translate into lower case
138         if( key >= 'a' && key <= 'z' )
139         {
140             key -= ('a' - 'A');
141         }
142         if( KeyModifier > 0 )
143             p_intf->p_sys->p_theme->EvtBank->TestShortcut( key , KeyModifier );
144     }
145
146     // Send event
147     else if( IsVLCEvent( msg ) )
148     {
149         if( !proc->EventProc( evt ) )
150         {
151             wxExit();
152             return;      // Exit VLC !
153         }
154     }
155     else if( gwnd == NULL )
156     {
157         for( win = p_intf->p_sys->p_theme->WindowList.begin();
158              win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
159         {
160             (*win)->ProcessEvent( evt );
161         }
162     }
163     else
164     {
165         // Find window matching with gwnd
166         for( win = p_intf->p_sys->p_theme->WindowList.begin();
167              win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
168         {
169             // If it is the correct window
170             if( gwnd == ( (GTK2Window *)(*win) )->GetHandle() )
171             {
172                 // Send event and check if processed
173                 if( (*win)->ProcessEvent( evt ) )
174                 {
175                     delete (OSEvent *)evt;
176                     return;
177                 }
178                 else
179                 {
180                     break;
181                 }
182             }
183         }
184     }
185
186     evt->DestructParameters();
187     delete (OSEvent *)evt;
188
189     // Check if vlc is closing
190     proc->IsClosing();
191
192     gtk_main_do_event( event )
193 }*/
194 //---------------------------------------------------------------------------
195
196
197 //---------------------------------------------------------------------------
198 // Implementation of Instance class
199 //---------------------------------------------------------------------------
200 #ifndef BASIC_SKINS
201 Instance::Instance( )
202 {
203 }
204
205 Instance::Instance( intf_thread_t *_p_intf )
206 {
207     // Initialization
208     p_intf = _p_intf;
209 }
210
211 IMPLEMENT_APP_NO_MAIN(Instance)
212
213 bool Instance::OnInit()
214 {
215     // Set event callback. Yes, it's a big hack ;)
216 //    gdk_event_handler_set( GTK2Proc, (gpointer)callbackobj, NULL );
217
218     p_intf->p_sys->p_icon = new wxIcon( vlc_xpm );
219     p_intf->p_sys->OpenDlg = new OpenDialog( p_intf, NULL, FILE_ACCESS );
220     p_intf->p_sys->MessagesDlg = new Messages( p_intf, NULL );
221     p_intf->p_sys->SoutDlg = new SoutDialog( p_intf, NULL );
222     p_intf->p_sys->PrefsDlg = new PrefsDialog( p_intf, NULL );
223     p_intf->p_sys->InfoDlg = new FileInfo( p_intf, NULL );
224     
225     // Add timer
226 //    g_timeout_add( 200, (GSourceFunc)RefreshTimer, (gpointer)p_intf );
227
228     return TRUE;
229 }
230 #endif
231
232
233 //---------------------------------------------------------------------------
234 // X11 event processing
235 //---------------------------------------------------------------------------
236 void ProcessEvent( intf_thread_t *p_intf, VlcProc *proc, XEvent *event )
237 {
238     // Variables
239     list<SkinWindow *>::const_iterator win;
240     unsigned int msg;
241     Event *evt;
242
243     Window wnd = ((XAnyEvent *)event)->window;
244     
245     // Create event to dispatch in windows
246     // Skin event
247
248     if( event->type == ClientMessage )
249     {
250         msg = ( (XClientMessageEvent *)event )->data.l[0];
251         evt = (Event *)new OSEvent( p_intf, 
252             ((XAnyEvent *)event)->window, msg,
253             ( (XClientMessageEvent *)event )->data.l[1],
254             ( (XClientMessageEvent *)event )->data.l[2] );
255     }
256     // System event
257     else
258     {
259         msg = event->type;
260         evt = (Event *)new OSEvent( p_intf,
261             ((XAnyEvent *)event)->window, msg, 0, (long)event );
262     }
263
264     // Process keyboard shortcuts
265     if( msg == KeyPress )
266     {
267 /*        int KeyModifier = 0;
268         // If key is ALT
269         if( ((GdkEventKey *)event)->state & GDK_MOD1_MASK )
270         {
271             KeyModifier = 1;
272         }
273         // If key is CTRL
274         else if( ((GdkEventKey *)event)->state & GDK_CONTROL_MASK )
275         {
276             KeyModifier = 2;
277         }
278         int key = ((GdkEventKey *)event)->keyval;
279         // Translate into lower case
280         if( key >= 'a' && key <= 'z' )
281         {
282             key -= ('a' - 'A');
283         }
284         if( KeyModifier > 0 )
285             p_intf->p_sys->p_theme->EvtBank->TestShortcut( key , KeyModifier );*/
286     }
287
288     // Send event
289     else if( IsVLCEvent( msg ) )
290     {
291         if( !proc->EventProc( evt ) )
292         {
293 //            wxExit();
294             return;      // Exit VLC !
295         }
296     }
297     else if( wnd == NULL )
298     {
299         for( win = p_intf->p_sys->p_theme->WindowList.begin();
300              win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
301         {
302             (*win)->ProcessEvent( evt );
303         }
304     }
305     else
306     {
307         // Find window matching with gwnd
308         for( win = p_intf->p_sys->p_theme->WindowList.begin();
309              win != p_intf->p_sys->p_theme->WindowList.end(); win++ )
310         {
311             // If it is the correct window
312             if( wnd == ( (X11Window *)(*win) )->GetHandle() )
313             {
314                 // Send event and check if processed
315                 if( (*win)->ProcessEvent( evt ) )
316                 {
317                     delete (OSEvent *)evt;
318                     return;
319                 }
320                 else
321                 {
322                     break;
323                 }
324             }
325         }
326     }
327
328     evt->DestructParameters();
329     delete (OSEvent *)evt;
330
331 // Check if vlc is closing
332     proc->IsClosing();
333
334 }
335
336
337 //---------------------------------------------------------------------------
338 // X11 interface
339 //---------------------------------------------------------------------------
340 void OSRun( intf_thread_t *p_intf )
341 {
342     static char  *p_args[] = { "" };
343
344     VlcProc *proc = new VlcProc( p_intf );
345     
346 #ifndef BASIC_SKINS
347     wxTheApp = new Instance( p_intf );
348     wxEntry( 1, p_args );
349 #endif
350
351     Display *display = ((OSTheme *)p_intf->p_sys->p_theme)->GetDisplay();
352     
353     // Main event loop
354     int count = 0;
355     while( 1 )
356     {
357         XEvent event;
358         while( XPending( display ) > 0 )
359         {
360             XNextEvent( display, &event );
361             ProcessEvent( p_intf, proc, &event );
362         }
363         usleep( 1000 );
364         if( ++count == 100 )
365         {
366             count = 0;
367             SkinManage( p_intf );    // Call every 100 ms
368         }
369     }
370     
371 }
372 //---------------------------------------------------------------------------
373 bool IsVLCEvent( unsigned int msg )
374 {
375     return( msg > VLC_MESSAGE && msg < VLC_WINDOW );
376 }
377 //---------------------------------------------------------------------------
378
379 #endif