preparation for allowing to use wxTimer in wxBase (heavily modified patch 1113088):
[wxWidgets.git] / src / dfb / evtloop.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/evtloop.cpp
3 // Purpose: wxEventLoop implementation
4 // Author: Vaclav Slavik
5 // Created: 2006-08-16
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ===========================================================================
12 // declarations
13 // ===========================================================================
14
15 // ---------------------------------------------------------------------------
16 // headers
17 // ---------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #include "wx/evtloop.h"
23
24 #ifndef WX_PRECOMP
25 #include "wx/app.h"
26 #endif
27
28 #include "wx/thread.h"
29 #include "wx/generic/private/timer.h"
30 #include "wx/private/selectdispatcher.h"
31 #include "wx/dfb/private.h"
32 #include "wx/nonownedwnd.h"
33
34 #define TRACE_EVENTS _T("events")
35
36 // ===========================================================================
37 // implementation
38 // ===========================================================================
39
40 //-----------------------------------------------------------------------------
41 // wxEventLoop initialization
42 //-----------------------------------------------------------------------------
43
44 wxIDirectFBEventBufferPtr wxEventLoop::ms_buffer;
45
46 wxEventLoop::wxEventLoop()
47 {
48 if ( !ms_buffer )
49 InitBuffer();
50 }
51
52 /* static */
53 void wxEventLoop::InitBuffer()
54 {
55 ms_buffer = wxIDirectFB::Get()->CreateEventBuffer();
56 }
57
58 /* static */
59 void wxEventLoop::CleanUp()
60 {
61 ms_buffer.Reset();
62 }
63
64 /* static */
65 wxIDirectFBEventBufferPtr wxEventLoop::GetDirectFBEventBuffer()
66 {
67 if ( !ms_buffer )
68 InitBuffer();
69
70 return ms_buffer;
71 }
72
73 //-----------------------------------------------------------------------------
74 // events dispatch and loop handling
75 //-----------------------------------------------------------------------------
76
77 bool wxEventLoop::Pending() const
78 {
79 wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") );
80
81 return ms_buffer->HasEvent();
82 }
83
84 bool wxEventLoop::Dispatch()
85 {
86 wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") );
87
88 // NB: we don't block indefinitely waiting for an event, but instead
89 // time out after a brief period in order to make sure that
90 // OnNextIteration() will be called frequently enough
91 const int TIMEOUT = 100;
92
93 // release the GUI mutex so that other threads have a chance to post
94 // events:
95 wxMutexGuiLeave();
96
97 bool rv = ms_buffer->WaitForEventWithTimeout(0, TIMEOUT);
98
99 // and acquire it back before calling any event handlers:
100 wxMutexGuiEnter();
101
102 if ( rv )
103 {
104 switch ( ms_buffer->GetLastResult() )
105 {
106 case DFB_OK:
107 {
108 wxDFBEvent e;
109 ms_buffer->GetEvent(e);
110 HandleDFBEvent(e);
111 break;
112 }
113
114 case DFB_TIMEOUT:
115 // timed out, pretend we processed an event so that
116 // OnNextIteration is called
117 break;
118
119 default:
120 // don't terminate the loop due to errors (they were reported
121 // already by ms_buffer)
122 break;
123 }
124 }
125
126 return true;
127 }
128
129 void wxEventLoop::WakeUp()
130 {
131 wxCHECK_RET( ms_buffer, _T("invalid event buffer") );
132
133 ms_buffer->WakeUp();
134 }
135
136 void wxEventLoop::OnNextIteration()
137 {
138 #if wxUSE_TIMER
139 wxGenericTimerImpl::NotifyTimers();
140 #endif
141
142 #if wxUSE_SOCKETS
143 // handle any pending socket events:
144 wxSelectDispatcher::Get().RunLoop(0);
145 #endif
146 }
147
148 void wxEventLoop::Yield()
149 {
150 // process all pending events:
151 while ( Pending() )
152 Dispatch();
153
154 // handle timers, sockets etc.
155 OnNextIteration();
156 }
157
158
159 //-----------------------------------------------------------------------------
160 // DirectFB -> wxWidgets events translation
161 //-----------------------------------------------------------------------------
162
163 void wxEventLoop::HandleDFBEvent(const wxDFBEvent& event)
164 {
165 switch ( event.GetClass() )
166 {
167 case DFEC_WINDOW:
168 {
169 wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
170 wxNonOwnedWindow::HandleDFBWindowEvent(winevent);
171 break;
172 }
173
174 case DFEC_NONE:
175 case DFEC_INPUT:
176 case DFEC_USER:
177 #if wxCHECK_DFB_VERSION(0,9,23)
178 case DFEC_UNIVERSAL:
179 #endif
180 {
181 wxLogTrace(TRACE_EVENTS,
182 _T("ignoring event of unsupported class %i"),
183 (int)event.GetClass());
184 }
185 }
186 }