src/events/SDL_quit.c
author Ethan Lee <flibitijibibo@flibitijibibo.com>
Wed, 17 Jul 2019 23:20:57 -0400
changeset 12950 05dddfb66b85
parent 12632 e8bea0d8c9f6
permissions -rw-r--r--
Copypaste SDL_NSLog to UIKit backend, document it as such
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@12503
     3
  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
icculus@8093
    21
#include "../SDL_internal.h"
icculus@9434
    22
#include "SDL_hints.h"
icculus@9720
    23
#include "SDL_assert.h"
slouken@0
    24
slouken@0
    25
/* General quit handling code for SDL */
slouken@0
    26
slouken@1330
    27
#ifdef HAVE_SIGNAL_H
slouken@0
    28
#include <signal.h>
slouken@0
    29
#endif
slouken@0
    30
slouken@0
    31
#include "SDL_events.h"
slouken@0
    32
#include "SDL_events_c.h"
slouken@0
    33
icculus@12632
    34
#if defined(HAVE_SIGNAL_H) || defined(HAVE_SIGACTION)
icculus@12632
    35
#define HAVE_SIGNAL_SUPPORT 1
icculus@12632
    36
#endif
icculus@12632
    37
icculus@12632
    38
#ifdef HAVE_SIGNAL_SUPPORT
icculus@9434
    39
static SDL_bool disable_signals = SDL_FALSE;
icculus@9720
    40
static SDL_bool send_quit_pending = SDL_FALSE;
icculus@9434
    41
icculus@12631
    42
#ifdef SDL_BACKGROUNDING_SIGNAL
icculus@12631
    43
static SDL_bool send_backgrounding_pending = SDL_FALSE;
icculus@12631
    44
#endif
icculus@12631
    45
icculus@12631
    46
#ifdef SDL_FOREGROUNDING_SIGNAL
icculus@12631
    47
static SDL_bool send_foregrounding_pending = SDL_FALSE;
icculus@12631
    48
#endif
icculus@12631
    49
slouken@1895
    50
static void
slouken@1895
    51
SDL_HandleSIG(int sig)
slouken@0
    52
{
slouken@1895
    53
    /* Reset the signal handler */
slouken@1895
    54
    signal(sig, SDL_HandleSIG);
slouken@0
    55
icculus@9720
    56
    /* Send a quit event next time the event loop pumps. */
icculus@9720
    57
    /* We can't send it in signal handler; malloc() might be interrupted! */
icculus@12631
    58
    if ((sig == SIGINT) || (sig == SIGTERM)) {
icculus@12631
    59
        send_quit_pending = SDL_TRUE;
icculus@12631
    60
    }
icculus@12631
    61
icculus@12631
    62
    #ifdef SDL_BACKGROUNDING_SIGNAL
icculus@12631
    63
    else if (sig == SDL_BACKGROUNDING_SIGNAL) {
icculus@12631
    64
        send_backgrounding_pending = SDL_TRUE;
icculus@12631
    65
    }
icculus@12631
    66
    #endif
icculus@12631
    67
icculus@12631
    68
    #ifdef SDL_FOREGROUNDING_SIGNAL
icculus@12631
    69
    else if (sig == SDL_FOREGROUNDING_SIGNAL) {
icculus@12631
    70
        send_foregrounding_pending = SDL_TRUE;
icculus@12631
    71
    }
icculus@12631
    72
    #endif
slouken@0
    73
}
slouken@0
    74
icculus@12631
    75
static void
icculus@12631
    76
SDL_EventSignal_Init(const int sig)
slouken@0
    77
{
slouken@5493
    78
#ifdef HAVE_SIGACTION
slouken@5493
    79
    struct sigaction action;
icculus@12631
    80
icculus@12631
    81
    sigaction(sig, NULL, &action);
icculus@5577
    82
#ifdef HAVE_SA_SIGACTION
slouken@11840
    83
    if ( action.sa_handler == SIG_DFL && (void (*)(int))action.sa_sigaction == SIG_DFL ) {
icculus@5577
    84
#else
icculus@5577
    85
    if ( action.sa_handler == SIG_DFL ) {
icculus@5577
    86
#endif
slouken@5493
    87
        action.sa_handler = SDL_HandleSIG;
icculus@12631
    88
        sigaction(sig, &action, NULL);
slouken@5493
    89
    }
slouken@5493
    90
#elif HAVE_SIGNAL_H
icculus@12631
    91
    void (*ohandler) (int) = signal(sig, SDL_HandleSIG);
icculus@12631
    92
    if (ohandler != SIG_DFL) {
icculus@12631
    93
        signal(sig, ohandler);
icculus@12631
    94
    }
icculus@12631
    95
#endif
icculus@12631
    96
}
slouken@0
    97
icculus@12631
    98
static void
icculus@12631
    99
SDL_EventSignal_Quit(const int sig)
icculus@12631
   100
{
icculus@12631
   101
#ifdef HAVE_SIGACTION
icculus@12631
   102
    struct sigaction action;
icculus@12631
   103
    sigaction(sig, NULL, &action);
icculus@12631
   104
    if ( action.sa_handler == SDL_HandleSIG ) {
icculus@12631
   105
        action.sa_handler = SIG_DFL;
icculus@12631
   106
        sigaction(sig, &action, NULL);
icculus@12631
   107
    }
icculus@12631
   108
#elif HAVE_SIGNAL_H
icculus@12631
   109
    void (*ohandler) (int) = signal(sig, SIG_DFL);
icculus@12631
   110
    if (ohandler != SDL_HandleSIG) {
icculus@12631
   111
        signal(sig, ohandler);
icculus@12631
   112
    }
icculus@12631
   113
#endif /* HAVE_SIGNAL_H */
icculus@12631
   114
}
icculus@12631
   115
icculus@12631
   116
/* Public functions */
icculus@12631
   117
static int
icculus@12631
   118
SDL_QuitInit_Internal(void)
icculus@12631
   119
{
slouken@1895
   120
    /* Both SIGINT and SIGTERM are translated into quit interrupts */
icculus@12631
   121
    /* and SDL can be built to simulate iOS/Android semantics with arbitrary signals. */
icculus@12631
   122
    SDL_EventSignal_Init(SIGINT);
icculus@12631
   123
    SDL_EventSignal_Init(SIGTERM);
icculus@12631
   124
icculus@12631
   125
    #ifdef SDL_BACKGROUNDING_SIGNAL
icculus@12631
   126
    SDL_EventSignal_Init(SDL_BACKGROUNDING_SIGNAL);
icculus@12631
   127
    #endif
icculus@12631
   128
icculus@12631
   129
    #ifdef SDL_FOREGROUNDING_SIGNAL
icculus@12631
   130
    SDL_EventSignal_Init(SDL_FOREGROUNDING_SIGNAL);
icculus@12631
   131
    #endif
slouken@0
   132
slouken@1895
   133
    /* That's it! */
icculus@9434
   134
    return 0;
slouken@0
   135
}
slouken@1895
   136
icculus@9436
   137
static void
icculus@9436
   138
SDL_QuitQuit_Internal(void)
icculus@9436
   139
{
icculus@12631
   140
    SDL_EventSignal_Quit(SIGINT);
icculus@12631
   141
    SDL_EventSignal_Quit(SIGTERM);
slouken@1123
   142
icculus@12631
   143
    #ifdef SDL_BACKGROUNDING_SIGNAL
icculus@12631
   144
    SDL_EventSignal_Quit(SDL_BACKGROUNDING_SIGNAL);
icculus@12631
   145
    #endif
icculus@12631
   146
icculus@12631
   147
    #ifdef SDL_FOREGROUNDING_SIGNAL
icculus@12631
   148
    SDL_EventSignal_Quit(SDL_FOREGROUNDING_SIGNAL);
icculus@12631
   149
    #endif
slouken@1123
   150
}
icculus@12632
   151
#endif
icculus@12632
   152
icculus@12632
   153
int
icculus@12632
   154
SDL_QuitInit(void)
icculus@12632
   155
{
icculus@12632
   156
#ifdef HAVE_SIGNAL_SUPPORT
icculus@12632
   157
    if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) {
icculus@12632
   158
        return SDL_QuitInit_Internal();
icculus@12632
   159
    }
icculus@12632
   160
#endif
icculus@12632
   161
    return 0;
icculus@12632
   162
}
slouken@0
   163
icculus@9436
   164
void
icculus@9436
   165
SDL_QuitQuit(void)
icculus@9436
   166
{
icculus@12632
   167
#ifdef HAVE_SIGNAL_SUPPORT
icculus@9436
   168
    if (!disable_signals) {
icculus@9436
   169
        SDL_QuitQuit_Internal();
icculus@9436
   170
    }
icculus@12632
   171
#endif
slouken@0
   172
}
slouken@1895
   173
icculus@9720
   174
void
icculus@12631
   175
SDL_SendPendingSignalEvents(void)
icculus@9720
   176
{
icculus@12632
   177
#ifdef HAVE_SIGNAL_SUPPORT
icculus@9720
   178
    if (send_quit_pending) {
icculus@9720
   179
        SDL_SendQuit();
icculus@9720
   180
        SDL_assert(!send_quit_pending);
icculus@9720
   181
    }
icculus@12631
   182
icculus@12631
   183
    #ifdef SDL_BACKGROUNDING_SIGNAL
icculus@12631
   184
    if (send_backgrounding_pending) {
icculus@12631
   185
        send_backgrounding_pending = SDL_FALSE;
icculus@12631
   186
        SDL_OnApplicationWillResignActive();
icculus@12631
   187
    }
icculus@12631
   188
    #endif
icculus@12631
   189
icculus@12631
   190
    #ifdef SDL_FOREGROUNDING_SIGNAL
icculus@12631
   191
    if (send_foregrounding_pending) {
icculus@12631
   192
        send_foregrounding_pending = SDL_FALSE;
icculus@12631
   193
        SDL_OnApplicationDidBecomeActive();
icculus@12631
   194
    }
icculus@12631
   195
    #endif
icculus@12632
   196
#endif
icculus@12632
   197
}
icculus@12632
   198
icculus@12632
   199
/* This function returns 1 if it's okay to close the application window */
icculus@12632
   200
int
icculus@12632
   201
SDL_SendQuit(void)
icculus@12632
   202
{
icculus@12632
   203
#ifdef HAVE_SIGNAL_SUPPORT
icculus@12632
   204
    send_quit_pending = SDL_FALSE;
icculus@12632
   205
#endif
icculus@12632
   206
    return SDL_SendAppEvent(SDL_QUIT);
icculus@9720
   207
}
icculus@9720
   208
slouken@1895
   209
/* vi: set ts=4 sw=4 expandtab: */