]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/appunix.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/appunix.cpp
3 // Purpose: wxAppConsole with wxMainLoop implementation
4 // Author: Lukasz Michalski
7 // Copyright: (c) Lukasz Michalski
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
22 #include "wx/evtloop.h"
23 #include "wx/scopedptr.h"
24 #include "wx/unix/private/wakeuppipe.h"
25 #include "wx/private/fdiodispatcher.h"
26 #include "wx/private/fdioeventloopsourcehandler.h"
32 // don't use for systems which don't define it (at least VMS and QNX)
36 // ----------------------------------------------------------------------------
37 // Helper class calling CheckSignal() on wake up
38 // ----------------------------------------------------------------------------
43 class SignalsWakeUpPipe
: public wxWakeUpPipe
46 // Ctor automatically registers this pipe with the event loop.
49 m_source
= wxEventLoopBase::AddSourceForFD
57 virtual void OnReadWaiting()
59 // The base class wxWakeUpPipe::OnReadWaiting() needs to be called in order
60 // to read the data out of the wake up pipe and clear it for next time.
61 wxWakeUpPipe::OnReadWaiting();
64 wxTheApp
->CheckSignal();
67 virtual ~SignalsWakeUpPipe()
73 wxEventLoopSource
* m_source
;
76 } // anonymous namespace
78 wxAppConsole::wxAppConsole()
80 m_signalWakeUpPipe
= NULL
;
83 wxAppConsole::~wxAppConsole()
85 delete m_signalWakeUpPipe
;
88 // use unusual names for arg[cv] to avoid clashes with wxApp members with the
90 bool wxAppConsole::Initialize(int& argc_
, wxChar
** argv_
)
92 if ( !wxAppConsoleBase::Initialize(argc_
, argv_
) )
95 sigemptyset(&m_signalsCaught
);
100 // The actual signal handler. It does as little as possible (because very few
101 // things are safe to do from inside a signal handler) and just ensures that
102 // CheckSignal() will be called later from SignalsWakeUpPipe::OnReadWaiting().
103 void wxAppConsole::HandleSignal(int signal
)
105 wxAppConsole
* const app
= wxTheApp
;
109 // Register the signal that is caught.
110 sigaddset(&(app
->m_signalsCaught
), signal
);
112 // Wake up the application for handling the signal.
114 // Notice that we must have a valid wake up pipe here as we only install
115 // our signal handlers after allocating it.
116 app
->m_signalWakeUpPipe
->WakeUpNoLock();
119 void wxAppConsole::CheckSignal()
121 for ( SignalHandlerHash::iterator it
= m_signalHandlerHash
.begin();
122 it
!= m_signalHandlerHash
.end();
126 if ( sigismember(&m_signalsCaught
, sig
) )
128 sigdelset(&m_signalsCaught
, sig
);
134 wxFDIOHandler
* wxAppConsole::RegisterSignalWakeUpPipe(wxFDIODispatcher
& dispatcher
)
136 wxCHECK_MSG( m_signalWakeUpPipe
, false, "Should be allocated" );
138 // we need a bridge to wxFDIODispatcher
140 // TODO: refactor the code so that only wxEventLoopSourceHandler is used
141 wxScopedPtr
<wxFDIOHandler
>
142 fdioHandler(new wxFDIOEventLoopSourceHandler(m_signalWakeUpPipe
));
144 if ( !dispatcher
.RegisterFD
146 m_signalWakeUpPipe
->GetReadFd(),
152 return fdioHandler
.release();
155 // the type of the signal handlers we use is "void(*)(int)" while the real
156 // signal handlers are extern "C" and so have incompatible type and at least
157 // Sun CC warns about it, so use explicit casts to suppress these warnings as
158 // they should be harmless
161 typedef void (*SignalHandler_t
)(int);
164 bool wxAppConsole::SetSignalHandler(int signal
, SignalHandler handler
)
166 const bool install
= (SignalHandler_t
)handler
!= SIG_DFL
&&
167 (SignalHandler_t
)handler
!= SIG_IGN
;
169 if ( !m_signalWakeUpPipe
)
171 // Create the pipe that the signal handler will use to cause the event
172 // loop to call wxAppConsole::CheckSignal().
173 m_signalWakeUpPipe
= new SignalsWakeUpPipe();
177 memset(&sa
, 0, sizeof(sa
));
178 sa
.sa_handler
= (SignalHandler_t
)&wxAppConsole::HandleSignal
;
179 sa
.sa_flags
= SA_RESTART
;
180 int res
= sigaction(signal
, &sa
, 0);
183 wxLogSysError(_("Failed to install signal handler"));
188 m_signalHandlerHash
[signal
] = handler
;
190 m_signalHandlerHash
.erase(signal
);