added wxEventLoop::DispatchTimeout()
[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/fdiodispatcher.h"
31 #include "wx/dfb/private.h"
32 #include "wx/nonownedwnd.h"
33
34 #define TRACE_EVENTS "events"
35
36 // ===========================================================================
37 // implementation
38 // ===========================================================================
39
40 //-----------------------------------------------------------------------------
41 // wxEventLoop initialization
42 //-----------------------------------------------------------------------------
43
44 wxIDirectFBEventBufferPtr wxGUIEventLoop::ms_buffer;
45
46 wxGUIEventLoop::wxGUIEventLoop()
47 {
48 if ( !ms_buffer )
49 InitBuffer();
50 }
51
52 /* static */
53 void wxGUIEventLoop::InitBuffer()
54 {
55 ms_buffer = wxIDirectFB::Get()->CreateEventBuffer();
56 }
57
58 /* static */
59 void wxGUIEventLoop::CleanUp()
60 {
61 ms_buffer.Reset();
62 }
63
64 /* static */
65 wxIDirectFBEventBufferPtr wxGUIEventLoop::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 wxGUIEventLoop::Pending() const
78 {
79 wxCHECK_MSG( ms_buffer, false, "invalid event buffer" );
80
81 return ms_buffer->HasEvent();
82 }
83
84 bool wxGUIEventLoop::Dispatch()
85 {
86 // NB: we don't block indefinitely waiting for an event, but instead
87 // time out after a brief period in order to make sure that
88 // OnNextIteration() will be called frequently enough
89 //
90 // TODO: remove this hack, instead use CreateFileDescriptor() to properly
91 // multiplex GUI and socket input
92 const int TIMEOUT = 100;
93
94 // treat time out (-1 return value) as normal successful return so that
95 // OnNextIteration() is called
96 return !!DispatchTimeout(TIMEOUT);
97 }
98
99 int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
100 {
101 wxCHECK_MSG( ms_buffer, 0, "invalid event buffer" );
102
103 // release the GUI mutex so that other threads have a chance to post
104 // events:
105 wxMutexGuiLeave();
106
107 bool rv = ms_buffer->WaitForEventWithTimeout(0, timeout);
108
109 // and acquire it back before calling any event handlers:
110 wxMutexGuiEnter();
111
112 if ( rv )
113 {
114 switch ( ms_buffer->GetLastResult() )
115 {
116 case DFB_OK:
117 {
118 wxDFBEvent e;
119 ms_buffer->GetEvent(e);
120 HandleDFBEvent(e);
121 break;
122 }
123
124 case DFB_TIMEOUT:
125 return -1;
126
127 default:
128 // don't terminate the loop due to errors (they were reported
129 // already by ms_buffer)
130 break;
131 }
132 }
133
134 return 1;
135 }
136
137 void wxGUIEventLoop::WakeUp()
138 {
139 wxCHECK_RET( ms_buffer, "invalid event buffer" );
140
141 ms_buffer->WakeUp();
142 }
143
144 void wxGUIEventLoop::OnNextIteration()
145 {
146 #if wxUSE_TIMER
147 wxGenericTimerImpl::NotifyTimers();
148 #endif
149
150 #if wxUSE_SOCKETS
151 // handle any pending socket events:
152 wxFDIODispatcher::DispatchPending();
153 #endif
154 }
155
156 void wxGUIEventLoop::Yield()
157 {
158 // process all pending events:
159 while ( Pending() )
160 Dispatch();
161
162 // handle timers, sockets etc.
163 OnNextIteration();
164 }
165
166
167 //-----------------------------------------------------------------------------
168 // DirectFB -> wxWidgets events translation
169 //-----------------------------------------------------------------------------
170
171 void wxGUIEventLoop::HandleDFBEvent(const wxDFBEvent& event)
172 {
173 switch ( event.GetClass() )
174 {
175 case DFEC_WINDOW:
176 {
177 wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
178 wxNonOwnedWindow::HandleDFBWindowEvent(winevent);
179 break;
180 }
181
182 case DFEC_NONE:
183 case DFEC_INPUT:
184 case DFEC_USER:
185 #if wxCHECK_DFB_VERSION(0,9,23)
186 case DFEC_UNIVERSAL:
187 #endif
188 {
189 wxLogTrace(TRACE_EVENTS,
190 "ignoring event of unsupported class %i",
191 (int)event.GetClass());
192 }
193 }
194 }