diff options
-rw-r--r-- | core/input/input.c | 2 | ||||
-rw-r--r-- | core/mp_msg.c | 18 | ||||
-rw-r--r-- | osdep/getch2-win.c | 3 | ||||
-rw-r--r-- | osdep/getch2.c | 113 | ||||
-rw-r--r-- | osdep/getch2.h | 5 |
5 files changed, 124 insertions, 17 deletions
diff --git a/core/input/input.c b/core/input/input.c index 1eedadf039..8b473dda43 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -32,6 +32,7 @@ #include <assert.h> #include "osdep/io.h" +#include "osdep/getch2.h" #include "input.h" #include "core/mp_fifo.h" @@ -1503,6 +1504,7 @@ static void read_all_fd_events(struct input_ctx *ictx, int time) static void read_all_events(struct input_ctx *ictx, int time) { + getch2_poll(); #ifdef CONFIG_COCOA cocoa_events_read_all_events(ictx, time); #else diff --git a/core/mp_msg.c b/core/mp_msg.c index 2e6f148438..85cbe9c1fa 100644 --- a/core/mp_msg.c +++ b/core/mp_msg.c @@ -31,6 +31,10 @@ #include <libintl.h> #endif +#ifndef __MINGW32__ +#include <signal.h> +#endif + #include "core/mp_msg.h" /* maximum message length of mp_msg */ @@ -79,6 +83,13 @@ void mp_msg_init(void){ GetConsoleScreenBufferInfo(hSTDOUT, &cinfo); stdoutAttrs = cinfo.wAttributes; #endif +#ifndef __MINGW32__ + struct sigaction sa; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGTTOU, &sa, NULL); // just write to stdout if you have to +#endif int i; char *env = getenv("MPV_VERBOSE"); if (env) @@ -98,6 +109,13 @@ void mp_msg_init(void){ int mp_msg_test(int mod, int lev) { +#ifndef __MINGW32__ + if (lev == MSGL_STATUS) { + // skip status line output if we are not in the foreground process group + if (tcgetpgrp(0) != getpgrp()) + return false; + } +#endif return lev <= (mp_msg_levels[mod] == -2 ? mp_msg_level_all + verbose : mp_msg_levels[mod]); } diff --git a/osdep/getch2-win.c b/osdep/getch2-win.c index c7607cee47..4bef70b418 100644 --- a/osdep/getch2-win.c +++ b/osdep/getch2-win.c @@ -166,6 +166,9 @@ bool getch2(struct mp_fifo *fifo) return true; } +void getch2_poll(void){ +} + void getch2_enable(void) { DWORD retval; diff --git a/osdep/getch2.c b/osdep/getch2.c index c722922f88..63aaa75bf1 100644 --- a/osdep/getch2.c +++ b/osdep/getch2.c @@ -55,11 +55,13 @@ #include "core/bstr.h" #include "core/mp_fifo.h" +#include "core/input/input.h" #include "core/input/keycodes.h" #include "getch2.h" #ifdef HAVE_TERMIOS -static struct termios tio_orig; +static volatile struct termios tio_orig; +static volatile int tio_orig_set; #endif static int getch2_len=0; static unsigned char getch2_buf[BUF_LEN]; @@ -284,39 +286,118 @@ bool getch2(struct mp_fifo *fifo) return true; } -static volatile int getch2_status=0; +static volatile int getch2_active=0; +static volatile int getch2_enabled=0; -static void do_enable_getch2(void) +static void do_activate_getch2(void) { + if (getch2_active) + return; #ifdef HAVE_TERMIOS struct termios tio_new; tcgetattr(0,&tio_new); + if (!tio_orig_set) { + tio_orig = tio_new; + tio_orig_set = 1; + } tio_new.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */ tio_new.c_cc[VMIN] = 1; tio_new.c_cc[VTIME] = 0; tcsetattr(0,TCSANOW,&tio_new); #endif + getch2_active=1; +} + +static void do_deactivate_getch2(void) +{ + if (!getch2_active) + return; +#ifdef HAVE_TERMIOS + if (tio_orig_set) { + // once set, it will never be set again + // so we can cast away volatile here + tcsetattr(0, TCSANOW, (const struct termios *) &tio_orig); + } +#endif + getch2_active=0; +} + +// sigaction wrapper +static int setsigaction(int signo, void (*handler) (int), + int flags, bool do_mask) +{ + struct sigaction sa; + sa.sa_handler = handler; + if(do_mask) + sigfillset(&sa.sa_mask); + else + sigemptyset(&sa.sa_mask); + sa.sa_flags = flags; + return sigaction(signo, &sa, NULL); +} + +void getch2_poll(void){ + if (!getch2_enabled) + return; + + // check if we are in the foreground process group + int newstatus = (tcgetpgrp(0) == getpgrp()); + + // and activate getch2 if we are, deactivate otherwise + if (newstatus) + do_activate_getch2(); + else + do_deactivate_getch2(); +} + +static void stop_sighandler(int signum) +{ + do_deactivate_getch2(); + + // note: for this signal, we use SA_RESETHAND but do NOT mask signals + // so this will invoke the default handler + raise(SIGTSTP); } static void continue_sighandler(int signum) { - if (getch2_status) - do_enable_getch2(); + // SA_RESETHAND has reset SIGTSTP, so we need to restore it here + setsigaction(SIGTSTP, stop_sighandler, SA_RESETHAND, false); + + getch2_poll(); +} + +static void quit_request_sighandler(int signum) +{ + async_quit_request = 1; } void getch2_enable(void){ -#ifdef HAVE_TERMIOS - tcgetattr(0,&tio_orig); - do_enable_getch2(); -#endif - getch2_status=1; - signal(SIGCONT,continue_sighandler); + if (getch2_enabled) + return; + + // handlers to fix terminal settings + setsigaction(SIGCONT, continue_sighandler, 0, true); + setsigaction(SIGTSTP, stop_sighandler, SA_RESETHAND, false); + setsigaction(SIGINT, quit_request_sighandler, SA_RESETHAND, false); + setsigaction(SIGTTIN, SIG_IGN, 0, true); + + do_activate_getch2(); + + getch2_enabled = 1; } void getch2_disable(void){ - if(!getch2_status) return; // already disabled / never enabled - getch2_status=0; -#ifdef HAVE_TERMIOS - tcsetattr(0,TCSANOW,&tio_orig); -#endif + if (!getch2_enabled) + return; + + // restore signals + setsigaction(SIGCONT, SIG_DFL, 0, false); + setsigaction(SIGTSTP, SIG_DFL, 0, false); + setsigaction(SIGINT, SIG_DFL, 0, false); + setsigaction(SIGTTIN, SIG_DFL, 0, false); + + do_deactivate_getch2(); + + getch2_enabled = 0; } diff --git a/osdep/getch2.h b/osdep/getch2.h index 85899b3ce3..5a04c4228e 100644 --- a/osdep/getch2.h +++ b/osdep/getch2.h @@ -41,10 +41,13 @@ void get_screen_size(void); /* Load key definitions from the TERMCAP database. 'termtype' can be NULL */ int load_termcap(char *termtype); -/* Enable and disable STDIN line-buffering */ +/* Initialize getch2 */ void getch2_enable(void); void getch2_disable(void); +/* Enable and disable STDIN line-buffering */ +void getch2_poll(void); + /* Read a character or a special key code (see keycodes.h) */ struct mp_fifo; bool getch2(struct mp_fifo *fifo); |