src/events/SDL_quit.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 22 Jun 2015 23:36:06 -0700
changeset 9776 952ff8a5076f
parent 9720 fd60d77139fc
child 9998 f67cf37e9cd4
permissions -rw-r--r--
Fixed bug 3030 - SDL_RecreateWindow fails to restore title, icon, etc.

Adam M.

It loses the title and icon when window recreation fails. For instance, this may happen when trying to create an OpenGL ES window on a system that doesn't support it. But at that point, the title and icon have already been lost.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 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@9434
    34
static SDL_bool disable_signals = SDL_FALSE;
icculus@9720
    35
static SDL_bool send_quit_pending = SDL_FALSE;
icculus@9434
    36
slouken@1330
    37
#ifdef HAVE_SIGNAL_H
slouken@1895
    38
static void
slouken@1895
    39
SDL_HandleSIG(int sig)
slouken@0
    40
{
slouken@1895
    41
    /* Reset the signal handler */
slouken@1895
    42
    signal(sig, SDL_HandleSIG);
slouken@0
    43
icculus@9720
    44
    /* Send a quit event next time the event loop pumps. */
icculus@9720
    45
    /* We can't send it in signal handler; malloc() might be interrupted! */
icculus@9720
    46
    send_quit_pending = SDL_TRUE;
slouken@0
    47
}
slouken@1330
    48
#endif /* HAVE_SIGNAL_H */
slouken@0
    49
slouken@0
    50
/* Public functions */
icculus@9436
    51
static int
icculus@9436
    52
SDL_QuitInit_Internal(void)
slouken@0
    53
{
slouken@5493
    54
#ifdef HAVE_SIGACTION
slouken@5493
    55
    struct sigaction action;
slouken@5493
    56
    sigaction(SIGINT, NULL, &action);
icculus@5577
    57
#ifdef HAVE_SA_SIGACTION
slouken@5501
    58
    if ( action.sa_handler == SIG_DFL && action.sa_sigaction == (void*)SIG_DFL ) {
icculus@5577
    59
#else
icculus@5577
    60
    if ( action.sa_handler == SIG_DFL ) {
icculus@5577
    61
#endif
slouken@5493
    62
        action.sa_handler = SDL_HandleSIG;
slouken@5493
    63
        sigaction(SIGINT, &action, NULL);
slouken@5493
    64
    }
slouken@5493
    65
    sigaction(SIGTERM, NULL, &action);
icculus@5577
    66
icculus@5577
    67
#ifdef HAVE_SA_SIGACTION
slouken@5501
    68
    if ( action.sa_handler == SIG_DFL && action.sa_sigaction == (void*)SIG_DFL ) {
icculus@5577
    69
#else
icculus@5577
    70
    if ( action.sa_handler == SIG_DFL ) {
icculus@5577
    71
#endif
slouken@5493
    72
        action.sa_handler = SDL_HandleSIG;
slouken@5493
    73
        sigaction(SIGTERM, &action, NULL);
slouken@5493
    74
    }
slouken@5493
    75
#elif HAVE_SIGNAL_H
slouken@1895
    76
    void (*ohandler) (int);
slouken@0
    77
slouken@1895
    78
    /* Both SIGINT and SIGTERM are translated into quit interrupts */
slouken@1895
    79
    ohandler = signal(SIGINT, SDL_HandleSIG);
slouken@1895
    80
    if (ohandler != SIG_DFL)
slouken@1895
    81
        signal(SIGINT, ohandler);
slouken@1895
    82
    ohandler = signal(SIGTERM, SDL_HandleSIG);
slouken@1895
    83
    if (ohandler != SIG_DFL)
slouken@1895
    84
        signal(SIGTERM, ohandler);
slouken@1330
    85
#endif /* HAVE_SIGNAL_H */
slouken@0
    86
slouken@1895
    87
    /* That's it! */
icculus@9434
    88
    return 0;
slouken@0
    89
}
slouken@1895
    90
icculus@9436
    91
int
icculus@9436
    92
SDL_QuitInit(void)
slouken@1123
    93
{
icculus@9436
    94
    const char *hint = SDL_GetHint(SDL_HINT_NO_SIGNAL_HANDLERS);
icculus@9436
    95
    disable_signals = hint && (SDL_atoi(hint) == 1);
icculus@9436
    96
    if (!disable_signals) {
icculus@9436
    97
        return SDL_QuitInit_Internal();
icculus@9434
    98
    }
icculus@9436
    99
    return 0;
icculus@9436
   100
}
icculus@9434
   101
icculus@9436
   102
static void
icculus@9436
   103
SDL_QuitQuit_Internal(void)
icculus@9436
   104
{
slouken@5493
   105
#ifdef HAVE_SIGACTION
slouken@5493
   106
    struct sigaction action;
slouken@5493
   107
    sigaction(SIGINT, NULL, &action);
slouken@5493
   108
    if ( action.sa_handler == SDL_HandleSIG ) {
slouken@5493
   109
        action.sa_handler = SIG_DFL;
slouken@5493
   110
        sigaction(SIGINT, &action, NULL);
slouken@5493
   111
    }
slouken@5493
   112
    sigaction(SIGTERM, NULL, &action);
slouken@5493
   113
    if ( action.sa_handler == SDL_HandleSIG ) {
slouken@5493
   114
        action.sa_handler = SIG_DFL;
slouken@5493
   115
        sigaction(SIGTERM, &action, NULL);
slouken@5493
   116
    }
slouken@5493
   117
#elif HAVE_SIGNAL_H
slouken@1895
   118
    void (*ohandler) (int);
slouken@1123
   119
slouken@1895
   120
    ohandler = signal(SIGINT, SIG_DFL);
slouken@1895
   121
    if (ohandler != SDL_HandleSIG)
slouken@1895
   122
        signal(SIGINT, ohandler);
slouken@1895
   123
    ohandler = signal(SIGTERM, SIG_DFL);
slouken@1895
   124
    if (ohandler != SDL_HandleSIG)
slouken@1895
   125
        signal(SIGTERM, ohandler);
slouken@1330
   126
#endif /* HAVE_SIGNAL_H */
slouken@1123
   127
}
slouken@0
   128
icculus@9436
   129
void
icculus@9436
   130
SDL_QuitQuit(void)
icculus@9436
   131
{
icculus@9436
   132
    if (!disable_signals) {
icculus@9436
   133
        SDL_QuitQuit_Internal();
icculus@9436
   134
    }
icculus@9436
   135
}
icculus@9436
   136
slouken@0
   137
/* This function returns 1 if it's okay to close the application window */
slouken@1895
   138
int
slouken@1895
   139
SDL_SendQuit(void)
slouken@0
   140
{
icculus@9720
   141
    send_quit_pending = SDL_FALSE;
slouken@7190
   142
    return SDL_SendAppEvent(SDL_QUIT);
slouken@0
   143
}
slouken@1895
   144
icculus@9720
   145
void
icculus@9720
   146
SDL_SendPendingQuit(void)
icculus@9720
   147
{
icculus@9720
   148
    if (send_quit_pending) {
icculus@9720
   149
        SDL_SendQuit();
icculus@9720
   150
        SDL_assert(!send_quit_pending);
icculus@9720
   151
    }
icculus@9720
   152
}
icculus@9720
   153
slouken@1895
   154
/* vi: set ts=4 sw=4 expandtab: */