Atlas - SDL_quit.c

Home / ext / SDL / src / events Lines: 1 | Size: 4917 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23// General quit handling code for SDL 24 25#ifdef HAVE_SIGNAL_H 26#include <signal.h> 27#endif 28 29#include "SDL_events_c.h" 30 31#if defined(HAVE_SIGNAL_H) || defined(HAVE_SIGACTION) 32#define HAVE_SIGNAL_SUPPORT 1 33#endif 34 35#ifdef HAVE_SIGNAL_SUPPORT 36static bool disable_signals = false; 37static bool send_quit_pending = false; 38 39#ifdef SDL_BACKGROUNDING_SIGNAL 40static bool send_backgrounding_pending = false; 41#endif 42 43#ifdef SDL_FOREGROUNDING_SIGNAL 44static bool send_foregrounding_pending = false; 45#endif 46 47static void SDL_HandleSIG(int sig) 48{ 49#ifndef HAVE_SIGACTION 50 // Reset the signal handler if it was installed with signal() 51 (void)signal(sig, SDL_HandleSIG); 52#endif 53 54 // Send a quit event next time the event loop pumps. 55 // We can't send it in signal handler; SDL_malloc() might be interrupted! 56 if ((sig == SIGINT) || (sig == SIGTERM)) { 57 send_quit_pending = true; 58 } 59 60#ifdef SDL_BACKGROUNDING_SIGNAL 61 else if (sig == SDL_BACKGROUNDING_SIGNAL) { 62 send_backgrounding_pending = true; 63 } 64#endif 65 66#ifdef SDL_FOREGROUNDING_SIGNAL 67 else if (sig == SDL_FOREGROUNDING_SIGNAL) { 68 send_foregrounding_pending = true; 69 } 70#endif 71} 72 73static void SDL_EventSignal_Init(const int sig) 74{ 75#ifdef HAVE_SIGACTION 76 struct sigaction action; 77 78 sigaction(sig, NULL, &action); 79#ifdef HAVE_SA_SIGACTION 80 if (action.sa_handler == SIG_DFL && (void (*)(int))action.sa_sigaction == SIG_DFL) { 81#else 82 if (action.sa_handler == SIG_DFL) { 83#endif 84 action.sa_handler = SDL_HandleSIG; 85 sigaction(sig, &action, NULL); 86 } 87#elif defined(HAVE_SIGNAL_H) 88 void (*ohandler)(int) = signal(sig, SDL_HandleSIG); 89 if (ohandler != SIG_DFL) { 90 signal(sig, ohandler); 91 } 92#endif 93} 94 95static void SDL_EventSignal_Quit(const int sig) 96{ 97#ifdef HAVE_SIGACTION 98 struct sigaction action; 99 sigaction(sig, NULL, &action); 100 if (action.sa_handler == SDL_HandleSIG) { 101 action.sa_handler = SIG_DFL; 102 sigaction(sig, &action, NULL); 103 } 104#elif defined(HAVE_SIGNAL_H) 105 void (*ohandler)(int) = signal(sig, SIG_DFL); 106 if (ohandler != SDL_HandleSIG) { 107 signal(sig, ohandler); 108 } 109#endif // HAVE_SIGNAL_H 110} 111 112// Public functions 113static bool SDL_QuitInit_Internal(void) 114{ 115 // Both SIGINT and SIGTERM are translated into quit interrupts 116 // and SDL can be built to simulate iOS/Android semantics with arbitrary signals. 117 SDL_EventSignal_Init(SIGINT); 118 SDL_EventSignal_Init(SIGTERM); 119 120#ifdef SDL_BACKGROUNDING_SIGNAL 121 SDL_EventSignal_Init(SDL_BACKGROUNDING_SIGNAL); 122#endif 123 124#ifdef SDL_FOREGROUNDING_SIGNAL 125 SDL_EventSignal_Init(SDL_FOREGROUNDING_SIGNAL); 126#endif 127 128 // That's it! 129 return true; 130} 131 132static void SDL_QuitQuit_Internal(void) 133{ 134 SDL_EventSignal_Quit(SIGINT); 135 SDL_EventSignal_Quit(SIGTERM); 136 137#ifdef SDL_BACKGROUNDING_SIGNAL 138 SDL_EventSignal_Quit(SDL_BACKGROUNDING_SIGNAL); 139#endif 140 141#ifdef SDL_FOREGROUNDING_SIGNAL 142 SDL_EventSignal_Quit(SDL_FOREGROUNDING_SIGNAL); 143#endif 144} 145#endif 146 147bool SDL_InitQuit(void) 148{ 149#ifdef HAVE_SIGNAL_SUPPORT 150 if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, false)) { 151 return SDL_QuitInit_Internal(); 152 } 153#endif 154 return true; 155} 156 157void SDL_QuitQuit(void) 158{ 159#ifdef HAVE_SIGNAL_SUPPORT 160 if (!disable_signals) { 161 SDL_QuitQuit_Internal(); 162 } 163#endif 164} 165 166void SDL_SendPendingSignalEvents(void) 167{ 168#ifdef HAVE_SIGNAL_SUPPORT 169 if (send_quit_pending) { 170 SDL_SendQuit(); 171 SDL_assert(!send_quit_pending); 172 } 173 174#ifdef SDL_BACKGROUNDING_SIGNAL 175 if (send_backgrounding_pending) { 176 send_backgrounding_pending = false; 177 SDL_OnApplicationWillEnterBackground(); 178 } 179#endif 180 181#ifdef SDL_FOREGROUNDING_SIGNAL 182 if (send_foregrounding_pending) { 183 send_foregrounding_pending = false; 184 SDL_OnApplicationDidEnterForeground(); 185 } 186#endif 187#endif 188} 189 190void SDL_SendQuit(void) 191{ 192#ifdef HAVE_SIGNAL_SUPPORT 193 send_quit_pending = false; 194#endif 195 SDL_SendAppEvent(SDL_EVENT_QUIT); 196} 197
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.