~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/unix/appunix.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/unix/appunix.cpp
 
3
// Purpose:     wxAppConsole with wxMainLoop implementation
 
4
// Author:      Lukasz Michalski
 
5
// Created:     28/01/2005
 
6
// Copyright:   (c) Lukasz Michalski
 
7
// Licence:     wxWindows licence
 
8
/////////////////////////////////////////////////////////////////////////////
 
9
 
 
10
#include "wx/wxprec.h"
 
11
 
 
12
#ifdef __BORLANDC__
 
13
    #pragma hdrstop
 
14
#endif
 
15
 
 
16
#ifndef WX_PRECOMP
 
17
    #include "wx/app.h"
 
18
    #include "wx/log.h"
 
19
#endif
 
20
 
 
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"
 
26
 
 
27
#include <signal.h>
 
28
#include <unistd.h>
 
29
 
 
30
#ifndef SA_RESTART
 
31
    // don't use for systems which don't define it (at least VMS and QNX)
 
32
    #define SA_RESTART 0
 
33
#endif
 
34
 
 
35
// ----------------------------------------------------------------------------
 
36
// Helper class calling CheckSignal() on wake up
 
37
// ----------------------------------------------------------------------------
 
38
 
 
39
namespace
 
40
{
 
41
 
 
42
class SignalsWakeUpPipe : public wxWakeUpPipe
 
43
{
 
44
public:
 
45
    // Ctor automatically registers this pipe with the event loop.
 
46
    SignalsWakeUpPipe()
 
47
    {
 
48
        m_source = wxEventLoopBase::AddSourceForFD
 
49
                                    (
 
50
                                        GetReadFd(),
 
51
                                        this,
 
52
                                        wxEVENT_SOURCE_INPUT
 
53
                                    );
 
54
    }
 
55
 
 
56
    virtual void OnReadWaiting()
 
57
    {
 
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();
 
61
 
 
62
        if ( wxTheApp )
 
63
            wxTheApp->CheckSignal();
 
64
    }
 
65
 
 
66
    virtual ~SignalsWakeUpPipe()
 
67
    {
 
68
        delete m_source;
 
69
    }
 
70
 
 
71
private:
 
72
    wxEventLoopSource* m_source;
 
73
};
 
74
 
 
75
} // anonymous namespace
 
76
 
 
77
wxAppConsole::wxAppConsole()
 
78
{
 
79
    m_signalWakeUpPipe = NULL;
 
80
}
 
81
 
 
82
wxAppConsole::~wxAppConsole()
 
83
{
 
84
    delete m_signalWakeUpPipe;
 
85
}
 
86
 
 
87
// use unusual names for arg[cv] to avoid clashes with wxApp members with the
 
88
// same names
 
89
bool wxAppConsole::Initialize(int& argc_, wxChar** argv_)
 
90
{
 
91
    if ( !wxAppConsoleBase::Initialize(argc_, argv_) )
 
92
        return false;
 
93
 
 
94
    sigemptyset(&m_signalsCaught);
 
95
 
 
96
    return true;
 
97
}
 
98
 
 
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)
 
103
{
 
104
    wxAppConsole * const app = wxTheApp;
 
105
    if ( !app )
 
106
        return;
 
107
 
 
108
    // Register the signal that is caught.
 
109
    sigaddset(&(app->m_signalsCaught), signal);
 
110
 
 
111
    // Wake up the application for handling the signal.
 
112
    //
 
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();
 
116
}
 
117
 
 
118
void wxAppConsole::CheckSignal()
 
119
{
 
120
    for ( SignalHandlerHash::iterator it = m_signalHandlerHash.begin();
 
121
          it != m_signalHandlerHash.end();
 
122
          ++it )
 
123
    {
 
124
        int sig = it->first;
 
125
        if ( sigismember(&m_signalsCaught, sig) )
 
126
        {
 
127
            sigdelset(&m_signalsCaught, sig);
 
128
            (it->second)(sig);
 
129
        }
 
130
    }
 
131
}
 
132
 
 
133
wxFDIOHandler* wxAppConsole::RegisterSignalWakeUpPipe(wxFDIODispatcher& dispatcher)
 
134
{
 
135
    wxCHECK_MSG( m_signalWakeUpPipe, NULL, "Should be allocated" );
 
136
 
 
137
    // we need a bridge to wxFDIODispatcher
 
138
    //
 
139
    // TODO: refactor the code so that only wxEventLoopSourceHandler is used
 
140
    wxScopedPtr<wxFDIOHandler>
 
141
        fdioHandler(new wxFDIOEventLoopSourceHandler(m_signalWakeUpPipe));
 
142
 
 
143
    if ( !dispatcher.RegisterFD
 
144
                     (
 
145
                      m_signalWakeUpPipe->GetReadFd(),
 
146
                      fdioHandler.get(),
 
147
                      wxFDIO_INPUT
 
148
                     ) )
 
149
        return NULL;
 
150
 
 
151
    return fdioHandler.release();
 
152
}
 
153
 
 
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
 
158
extern "C"
 
159
{
 
160
    typedef void (*SignalHandler_t)(int);
 
161
}
 
162
 
 
163
bool wxAppConsole::SetSignalHandler(int signal, SignalHandler handler)
 
164
{
 
165
    const bool install = (SignalHandler_t)handler != SIG_DFL &&
 
166
                         (SignalHandler_t)handler != SIG_IGN;
 
167
 
 
168
    if ( !m_signalWakeUpPipe )
 
169
    {
 
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();
 
173
    }
 
174
 
 
175
    struct sigaction sa;
 
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);
 
180
    if ( res != 0 )
 
181
    {
 
182
        wxLogSysError(_("Failed to install signal handler"));
 
183
        return false;
 
184
    }
 
185
 
 
186
    if ( install )
 
187
        m_signalHandlerHash[signal] = handler;
 
188
    else
 
189
        m_signalHandlerHash.erase(signal);
 
190
 
 
191
    return true;
 
192
}
 
193