wxDFB: fix events processing to support sockets events
[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/timer.h"
29 #include "wx/private/socketevtdispatch.h"
30 #include "wx/dfb/private.h"
31
32 #define TRACE_EVENTS _T("events")
33
34 // ===========================================================================
35 // implementation
36 // ===========================================================================
37
38 //-----------------------------------------------------------------------------
39 // wxEventLoop initialization
40 //-----------------------------------------------------------------------------
41
42 wxIDirectFBEventBufferPtr wxEventLoop::ms_buffer;
43
44 wxEventLoop::wxEventLoop()
45 {
46 if ( !ms_buffer )
47 InitBuffer();
48 }
49
50 /* static */
51 void wxEventLoop::InitBuffer()
52 {
53 ms_buffer = wxIDirectFB::Get()->CreateEventBuffer();
54 }
55
56 /* static */
57 void wxEventLoop::CleanUp()
58 {
59 ms_buffer.Reset();
60 }
61
62 /* static */
63 wxIDirectFBEventBufferPtr wxEventLoop::GetDirectFBEventBuffer()
64 {
65 if ( !ms_buffer )
66 InitBuffer();
67
68 return ms_buffer;
69 }
70
71 //-----------------------------------------------------------------------------
72 // events dispatch and loop handling
73 //-----------------------------------------------------------------------------
74
75 bool wxEventLoop::Pending() const
76 {
77 wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") );
78
79 return ms_buffer->HasEvent();
80 }
81
82 bool wxEventLoop::Dispatch()
83 {
84 wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") );
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 const int TIMEOUT = 100;
90
91 if ( ms_buffer->WaitForEventWithTimeout(0, TIMEOUT) )
92 {
93 switch ( ms_buffer->GetLastResult() )
94 {
95 case DFB_OK:
96 {
97 wxDFBEvent e;
98 ms_buffer->GetEvent(e);
99 HandleDFBEvent(e);
100 break;
101 }
102
103 case DFB_TIMEOUT:
104 // timed out, pretend we processed an event so that
105 // OnNextIteration is called
106 break;
107
108 default:
109 // don't terminate the loop due to errors (they were reported
110 // already by ms_buffer)
111 break;
112 }
113 }
114
115 return true;
116 }
117
118 void wxEventLoop::WakeUp()
119 {
120 wxCHECK_RET( ms_buffer, _T("invalid event buffer") );
121
122 ms_buffer->WakeUp();
123 }
124
125 void wxEventLoop::OnNextIteration()
126 {
127 #if wxUSE_TIMER
128 wxTimer::NotifyTimers();
129 #endif
130
131 #if wxUSE_SOCKETS
132 // handle any pending socket events:
133 wxSocketEventDispatcher::Get().RunLoop();
134 #endif
135 }
136
137 void wxEventLoop::Yield()
138 {
139 // process all pending events:
140 while ( Pending() )
141 Dispatch();
142
143 // handle timers, sockets etc.
144 OnNextIteration();
145 }
146
147
148 //-----------------------------------------------------------------------------
149 // DirectFB -> wxWidgets events translation
150 //-----------------------------------------------------------------------------
151
152 void wxEventLoop::HandleDFBEvent(const wxDFBEvent& event)
153 {
154 switch ( event.GetClass() )
155 {
156 case DFEC_WINDOW:
157 {
158 wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
159 wxTopLevelWindowDFB::HandleDFBWindowEvent(winevent);
160 break;
161 }
162
163 case DFEC_NONE:
164 case DFEC_INPUT:
165 case DFEC_USER:
166 #if wxCHECK_DFB_VERSION(0,9,23)
167 case DFEC_UNIVERSAL:
168 #endif
169 {
170 wxLogTrace(TRACE_EVENTS,
171 _T("ignoring event of unsupported class %i"),
172 (int)event.GetClass());
173 }
174 }
175 }