]> git.saurik.com Git - wxWidgets.git/blame - src/dfb/evtloop.cpp
Avoid calling gtk_window_get_position() from "configure-event" handler, if possible.
[wxWidgets.git] / src / dfb / evtloop.cpp
CommitLineData
b3c86150
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/dfb/evtloop.cpp
3// Purpose: wxEventLoop implementation
4// Author: Vaclav Slavik
5// Created: 2006-08-16
b3c86150
VS
6// Copyright: (c) 2006 REA Elektronik GmbH
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// ===========================================================================
11// declarations
12// ===========================================================================
13
14// ---------------------------------------------------------------------------
15// headers
16// ---------------------------------------------------------------------------
17
18// For compilers that support precompilation, includes "wx.h".
19#include "wx/wxprec.h"
20
21#include "wx/evtloop.h"
22
23#ifndef WX_PRECOMP
24 #include "wx/app.h"
bcf79477 25 #include "wx/log.h"
b3c86150
VS
26#endif
27
f7a50432 28#include "wx/thread.h"
4eba3923 29#include "wx/private/fdiodispatcher.h"
b3c86150 30#include "wx/dfb/private.h"
0edbcd60 31#include "wx/nonownedwnd.h"
86e9b8f2 32#include "wx/buffer.h"
b3c86150 33
b3eb776a
VZ
34#include <errno.h>
35
a5001e93 36#define TRACE_EVENTS "events"
b3c86150
VS
37
38// ===========================================================================
39// implementation
40// ===========================================================================
41
86e9b8f2
VS
42//-----------------------------------------------------------------------------
43// wxDFBEventsHandler
44//-----------------------------------------------------------------------------
45
46// This handler is installed to process input on DirectFB's events socket (
47// obtained using CreateFileDescriptor()). When IDirectFBEventBuffer is used
48// in this mode, events are written to the file descriptor and we read them
49// in OnReadWaiting() below.
50class wxDFBEventsHandler : public wxFDIOHandler
51{
52public:
53 wxDFBEventsHandler()
54 : m_fd(-1), m_offset(0)
55 {}
56
57 void SetFD(int fd) { m_fd = fd; }
58
59 void Reset()
60 {
61 m_fd = -1;
62 m_offset = 0;
63 }
64
65 // implement wxFDIOHandler pure virtual methods
66 virtual void OnReadWaiting();
67 virtual void OnWriteWaiting()
68 { wxFAIL_MSG("OnWriteWaiting shouldn't be called"); }
69 virtual void OnExceptionWaiting()
70 { wxFAIL_MSG("OnExceptionWaiting shouldn't be called"); }
71
72private:
73 // DirectFB -> wxWidgets events translation
74 void HandleDFBEvent(const wxDFBEvent& event);
75
76 int m_fd;
77 size_t m_offset;
78 DFBEvent m_event;
79};
80
81void wxDFBEventsHandler::OnReadWaiting()
82{
83 for ( ;; )
84 {
85 int size = read(m_fd,
86 ((char*)&m_event) + m_offset,
87 sizeof(m_event) - m_offset);
88
89 if ( size == 0 || (size == -1 && (errno == EAGAIN || errno == EINTR)) )
90 {
91 // nothing left in the pipe (EAGAIN is expected for an FD with
92 // O_NONBLOCK)
93 break;
94 }
95
96 if ( size == -1 )
97 {
98 wxLogSysError(_("Failed to read event from DirectFB pipe"));
99 break;
100 }
101
102 size += m_offset;
103 m_offset = 0;
104
105 if ( size != sizeof(m_event) )
106 {
107 m_offset = size;
108 break;
109 }
110
111 HandleDFBEvent(m_event);
112 }
113}
114
115void wxDFBEventsHandler::HandleDFBEvent(const wxDFBEvent& event)
116{
117 switch ( event.GetClass() )
118 {
119 case DFEC_WINDOW:
120 {
121 wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
122 wxNonOwnedWindow::HandleDFBWindowEvent(winevent);
123 break;
124 }
125
126 case DFEC_NONE:
127 case DFEC_INPUT:
128 case DFEC_USER:
129#if wxCHECK_DFB_VERSION(0,9,23)
130 case DFEC_UNIVERSAL:
131#endif
132 {
133 wxLogTrace(TRACE_EVENTS,
134 "ignoring event of unsupported class %i",
135 (int)event.GetClass());
136 }
137 }
138}
139
b3c86150
VS
140//-----------------------------------------------------------------------------
141// wxEventLoop initialization
142//-----------------------------------------------------------------------------
143
b46b1d59 144wxIDirectFBEventBufferPtr wxGUIEventLoop::ms_buffer;
86e9b8f2
VS
145int wxGUIEventLoop::ms_bufferFd;
146static wxDFBEventsHandler gs_DFBEventsHandler;
b3c86150 147
b46b1d59 148wxGUIEventLoop::wxGUIEventLoop()
b3c86150 149{
86e9b8f2
VS
150 // Note that this has to be done here so that the buffer is ready when
151 // an event loop runs; GetDirectFBEventBuffer(), which also calls
152 // InitBuffer(), may be called before or after the first wxGUIEventLoop
153 // instance is created.
b3c86150
VS
154 if ( !ms_buffer )
155 InitBuffer();
156}
157
158/* static */
b46b1d59 159void wxGUIEventLoop::InitBuffer()
b3c86150 160{
86e9b8f2 161 // create DirectFB events buffer:
52c8d32a 162 ms_buffer = wxIDirectFB::Get()->CreateEventBuffer();
86e9b8f2
VS
163
164 // and setup a file descriptor that we can watch for new events:
165
166 ms_buffer->CreateFileDescriptor(&ms_bufferFd);
167 int flags = fcntl(ms_bufferFd, F_GETFL, 0);
168 if ( flags == -1 || fcntl(ms_bufferFd, F_SETFL, flags | O_NONBLOCK) == -1 )
169 {
170 wxLogSysError(_("Failed to switch DirectFB pipe to non-blocking mode"));
171 return;
172 }
173
174 wxFDIODispatcher *dispatcher = wxFDIODispatcher::Get();
175 wxCHECK_RET( dispatcher, "wxDFB requires wxFDIODispatcher" );
176
177 gs_DFBEventsHandler.SetFD(ms_bufferFd);
178 dispatcher->RegisterFD(ms_bufferFd, &gs_DFBEventsHandler, wxFDIO_INPUT);
b3c86150
VS
179}
180
e48a3055 181/* static */
b46b1d59 182void wxGUIEventLoop::CleanUp()
e48a3055 183{
86e9b8f2
VS
184 wxFDIODispatcher *dispatcher = wxFDIODispatcher::Get();
185 wxCHECK_RET( dispatcher, "wxDFB requires wxFDIODispatcher" );
186 dispatcher->UnregisterFD(ms_bufferFd);
187
e48a3055 188 ms_buffer.Reset();
86e9b8f2 189 gs_DFBEventsHandler.Reset();
e48a3055
VS
190}
191
b3c86150 192/* static */
b46b1d59 193wxIDirectFBEventBufferPtr wxGUIEventLoop::GetDirectFBEventBuffer()
b3c86150
VS
194{
195 if ( !ms_buffer )
196 InitBuffer();
197
198 return ms_buffer;
199}
200
201//-----------------------------------------------------------------------------
202// events dispatch and loop handling
203//-----------------------------------------------------------------------------
204
dde19c21 205bool wxGUIEventLoop::YieldFor(long eventsToProcess)
757b694b 206{
dde19c21
FM
207#if wxUSE_THREADS
208 if ( !wxThread::IsMain() )
209 return true; // can't process events from other threads
210#endif // wxUSE_THREADS
211
212 m_isInsideYield = true;
213 m_eventsToProcessInsideYield = eventsToProcess;
214
215#if wxUSE_LOG
216 wxLog::Suspend();
217#endif // wxUSE_LOG
218
d48b06bd
FM
219 // TODO: implement event filtering using the eventsToProcess mask
220
757b694b
VS
221 // process all pending events:
222 while ( Pending() )
223 Dispatch();
224
225 // handle timers, sockets etc.
226 OnNextIteration();
dde19c21
FM
227
228 // it's necessary to call ProcessIdle() to update the frames sizes which
229 // might have been changed (it also will update other things set from
230 // OnUpdateUI() which is a nice (and desired) side effect)
231 while ( ProcessIdle() ) {}
232
233#if wxUSE_LOG
234 wxLog::Resume();
235#endif // wxUSE_LOG
236
237 m_isInsideYield = false;
238
239 return true;
757b694b 240}