1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997-2012 Sam Lantinga
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19    Sam Lantinga
20    slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24/* General quit handling code for SDL */
25
26#ifdef HAVE_SIGNAL_H
27#include <signal.h>
28#endif
29
30#include "SDL_events.h"
31#include "SDL_events_c.h"
32
33
34#ifdef HAVE_SIGNAL_H
35static void SDL_HandleSIG(int sig)
36{
37	/* Reset the signal handler */
38	signal(sig, SDL_HandleSIG);
39
40	/* Signal a quit interrupt */
41	SDL_PrivateQuit();
42}
43#endif /* HAVE_SIGNAL_H */
44
45/* Public functions */
46int SDL_QuitInit(void)
47{
48#ifdef HAVE_SIGACTION
49	struct sigaction action;
50	sigaction(SIGINT, NULL, &action);
51#  ifdef HAVE_SA_SIGACTION
52	if ( action.sa_handler == SIG_DFL && action.sa_sigaction == (void*)SIG_DFL ) {
53#  else
54	if ( action.sa_handler == SIG_DFL ) {
55#  endif
56		action.sa_handler = SDL_HandleSIG;
57		sigaction(SIGINT, &action, NULL);
58	}
59	sigaction(SIGTERM, NULL, &action);
60#  ifdef HAVE_SA_SIGACTION
61	if ( action.sa_handler == SIG_DFL && action.sa_sigaction == (void*)SIG_DFL ) {
62#  else
63	if ( action.sa_handler == SIG_DFL ) {
64#  endif
65		action.sa_handler = SDL_HandleSIG;
66		sigaction(SIGTERM, &action, NULL);
67	}
68#elif HAVE_SIGNAL_H
69	void (*ohandler)(int);
70
71	/* Both SIGINT and SIGTERM are translated into quit interrupts */
72	ohandler = signal(SIGINT, SDL_HandleSIG);
73	if ( ohandler != SIG_DFL )
74		signal(SIGINT, ohandler);
75	ohandler = signal(SIGTERM, SDL_HandleSIG);
76	if ( ohandler != SIG_DFL )
77		signal(SIGTERM, ohandler);
78#endif /* HAVE_SIGNAL_H */
79
80	/* That's it! */
81	return(0);
82}
83void SDL_QuitQuit(void)
84{
85#ifdef HAVE_SIGACTION
86	struct sigaction action;
87	sigaction(SIGINT, NULL, &action);
88	if ( action.sa_handler == SDL_HandleSIG ) {
89		action.sa_handler = SIG_DFL;
90		sigaction(SIGINT, &action, NULL);
91	}
92	sigaction(SIGTERM, NULL, &action);
93	if ( action.sa_handler == SDL_HandleSIG ) {
94		action.sa_handler = SIG_DFL;
95		sigaction(SIGTERM, &action, NULL);
96	}
97#elif HAVE_SIGNAL_H
98	void (*ohandler)(int);
99
100	ohandler = signal(SIGINT, SIG_DFL);
101	if ( ohandler != SDL_HandleSIG )
102		signal(SIGINT, ohandler);
103	ohandler = signal(SIGTERM, SIG_DFL);
104	if ( ohandler != SDL_HandleSIG )
105		signal(SIGTERM, ohandler);
106#endif /* HAVE_SIGNAL_H */
107}
108
109/* This function returns 1 if it's okay to close the application window */
110int SDL_PrivateQuit(void)
111{
112	int posted;
113
114	posted = 0;
115	if ( SDL_ProcessEvents[SDL_QUIT] == SDL_ENABLE ) {
116		SDL_Event event;
117		event.type = SDL_QUIT;
118		if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) {
119			posted = 1;
120			SDL_PushEvent(&event);
121		}
122	}
123	return(posted);
124}
125