1
0
Fork 0
mirror of https://gitlab.com/sortix/sortix.git synced 2023-02-13 20:55:38 -05:00

Restore terminal when games quit.

This commit is contained in:
Jonas 'Sortie' Termansen 2016-01-25 16:30:43 +01:00
parent bff1265d62
commit c8bbd6e0aa
2 changed files with 84 additions and 2 deletions

View file

@ -1,6 +1,6 @@
/******************************************************************************* /*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2014. Copyright(C) Jonas 'Sortie' Termansen 2014, 2015, 2016.
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
@ -28,8 +28,11 @@
#include <errno.h> #include <errno.h>
#include <error.h> #include <error.h>
#include <math.h> #include <math.h>
#include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <time.h> #include <time.h>
#include <timespec.h> #include <timespec.h>
#include <unistd.h> #include <unistd.h>
@ -369,9 +372,48 @@ void mainloop(struct dispd_window* window)
} }
} }
// Reset the terminal state when the process terminates.
static struct termios saved_tio;
static void restore_terminal_on_exit(void)
{
tcsetattr(0, TCSAFLUSH, &saved_tio);
}
static void restore_terminal_on_signal(int signum)
{
if ( signum == SIGTSTP )
{
struct termios tio;
tcgetattr(0, &tio);
tcsetattr(0, TCSAFLUSH, &saved_tio);
raise(SIGSTOP);
tcgetattr(0, &saved_tio);
tcsetattr(0, TCSAFLUSH, &tio);
return;
}
tcsetattr(0, TCSAFLUSH, &saved_tio);
raise(signum);
}
// Create a display context, run the game, and then cleanly exit. // Create a display context, run the game, and then cleanly exit.
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if ( !isatty(0) )
error(1, errno, "standard input");
if ( tcgetattr(0, &saved_tio) < 0 )
error(1, errno, "tcsetattr: standard input");
if ( atexit(restore_terminal_on_exit) != 0 )
error(1, errno, "atexit");
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = restore_terminal_on_signal;
sigaction(SIGTSTP, &sa, NULL);
sa.sa_flags = SA_RESETHAND;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
if ( !dispd_initialize(&argc, &argv) ) if ( !dispd_initialize(&argc, &argv) )
error(1, 0, "couldn't initialize dispd library"); error(1, 0, "couldn't initialize dispd library");
struct dispd_session* session = dispd_attach_default_session(); struct dispd_session* session = dispd_attach_default_session();

View file

@ -1,6 +1,6 @@
/******************************************************************************* /*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015. Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015, 2016.
This program is free software: you can redistribute it and/or modify it This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
@ -28,11 +28,13 @@
#include <error.h> #include <error.h>
#include <fcntl.h> #include <fcntl.h>
#include <math.h> #include <math.h>
#include <signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <termios.h>
#include <time.h> #include <time.h>
#include <timespec.h> #include <timespec.h>
#include <unistd.h> #include <unistd.h>
@ -1173,8 +1175,46 @@ void InitGame()
new AsteroidField; new AsteroidField;
} }
static struct termios saved_tio;
static void restore_terminal_on_exit(void)
{
tcsetattr(0, TCSAFLUSH, &saved_tio);
}
static void restore_terminal_on_signal(int signum)
{
if ( signum == SIGTSTP )
{
struct termios tio;
tcgetattr(0, &tio);
tcsetattr(0, TCSAFLUSH, &saved_tio);
raise(SIGSTOP);
tcgetattr(0, &saved_tio);
tcsetattr(0, TCSAFLUSH, &tio);
return;
}
tcsetattr(0, TCSAFLUSH, &saved_tio);
raise(signum);
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if ( !isatty(0) )
error(1, errno, "standard input");
if ( tcgetattr(0, &saved_tio) < 0 )
error(1, errno, "tcsetattr: standard input");
if ( atexit(restore_terminal_on_exit) != 0 )
error(1, errno, "atexit");
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = restore_terminal_on_signal;
sigaction(SIGTSTP, &sa, NULL);
sa.sa_flags = SA_RESETHAND;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
if ( !dispd_initialize(&argc, &argv) ) if ( !dispd_initialize(&argc, &argv) )
error(1, 0, "couldn't initialize dispd library"); error(1, 0, "couldn't initialize dispd library");
struct dispd_session* session = dispd_attach_default_session(); struct dispd_session* session = dispd_attach_default_session();