1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/unix/appunix.cpp
3
// Purpose: wxAppConsole with wxMainLoop implementation
4
// Author: Lukasz Michalski
6
// Copyright: (c) Lukasz Michalski
7
// Licence: wxWindows licence
8
/////////////////////////////////////////////////////////////////////////////
10
#include "wx/wxprec.h"
21
#include "wx/evtloop.h"
22
#include "wx/scopedptr.h"
23
#include "wx/unix/private/wakeuppipe.h"
24
#include "wx/private/fdiodispatcher.h"
25
#include "wx/private/fdioeventloopsourcehandler.h"
31
// don't use for systems which don't define it (at least VMS and QNX)
35
// ----------------------------------------------------------------------------
36
// Helper class calling CheckSignal() on wake up
37
// ----------------------------------------------------------------------------
42
class SignalsWakeUpPipe : public wxWakeUpPipe
45
// Ctor automatically registers this pipe with the event loop.
48
m_source = wxEventLoopBase::AddSourceForFD
56
virtual void OnReadWaiting()
58
// The base class wxWakeUpPipe::OnReadWaiting() needs to be called in order
59
// to read the data out of the wake up pipe and clear it for next time.
60
wxWakeUpPipe::OnReadWaiting();
63
wxTheApp->CheckSignal();
66
virtual ~SignalsWakeUpPipe()
72
wxEventLoopSource* m_source;
75
} // anonymous namespace
77
wxAppConsole::wxAppConsole()
79
m_signalWakeUpPipe = NULL;
82
wxAppConsole::~wxAppConsole()
84
delete m_signalWakeUpPipe;
87
// use unusual names for arg[cv] to avoid clashes with wxApp members with the
89
bool wxAppConsole::Initialize(int& argc_, wxChar** argv_)
91
if ( !wxAppConsoleBase::Initialize(argc_, argv_) )
94
sigemptyset(&m_signalsCaught);
99
// The actual signal handler. It does as little as possible (because very few
100
// things are safe to do from inside a signal handler) and just ensures that
101
// CheckSignal() will be called later from SignalsWakeUpPipe::OnReadWaiting().
102
void wxAppConsole::HandleSignal(int signal)
104
wxAppConsole * const app = wxTheApp;
108
// Register the signal that is caught.
109
sigaddset(&(app->m_signalsCaught), signal);
111
// Wake up the application for handling the signal.
113
// Notice that we must have a valid wake up pipe here as we only install
114
// our signal handlers after allocating it.
115
app->m_signalWakeUpPipe->WakeUpNoLock();
118
void wxAppConsole::CheckSignal()
120
for ( SignalHandlerHash::iterator it = m_signalHandlerHash.begin();
121
it != m_signalHandlerHash.end();
125
if ( sigismember(&m_signalsCaught, sig) )
127
sigdelset(&m_signalsCaught, sig);
133
wxFDIOHandler* wxAppConsole::RegisterSignalWakeUpPipe(wxFDIODispatcher& dispatcher)
135
wxCHECK_MSG( m_signalWakeUpPipe, NULL, "Should be allocated" );
137
// we need a bridge to wxFDIODispatcher
139
// TODO: refactor the code so that only wxEventLoopSourceHandler is used
140
wxScopedPtr<wxFDIOHandler>
141
fdioHandler(new wxFDIOEventLoopSourceHandler(m_signalWakeUpPipe));
143
if ( !dispatcher.RegisterFD
145
m_signalWakeUpPipe->GetReadFd(),
151
return fdioHandler.release();
154
// the type of the signal handlers we use is "void(*)(int)" while the real
155
// signal handlers are extern "C" and so have incompatible type and at least
156
// Sun CC warns about it, so use explicit casts to suppress these warnings as
157
// they should be harmless
160
typedef void (*SignalHandler_t)(int);
163
bool wxAppConsole::SetSignalHandler(int signal, SignalHandler handler)
165
const bool install = (SignalHandler_t)handler != SIG_DFL &&
166
(SignalHandler_t)handler != SIG_IGN;
168
if ( !m_signalWakeUpPipe )
170
// Create the pipe that the signal handler will use to cause the event
171
// loop to call wxAppConsole::CheckSignal().
172
m_signalWakeUpPipe = new SignalsWakeUpPipe();
176
memset(&sa, 0, sizeof(sa));
177
sa.sa_handler = (SignalHandler_t)&wxAppConsole::HandleSignal;
178
sa.sa_flags = SA_RESTART;
179
int res = sigaction(signal, &sa, 0);
182
wxLogSysError(_("Failed to install signal handler"));
187
m_signalHandlerHash[signal] = handler;
189
m_signalHandlerHash.erase(signal);