]>
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
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
);