From db82e1be3a650225f2902927d034c7ff434b513d Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sat, 20 Jun 2015 15:00:12 +0200 Subject: fixed CTRL+C handling on PDCurses/win32 port * it now works as in the ncurses port: ^C during macro execution interrupts just as SIGINT does; else it is read as a character. * On Windows we need to register a special "console ctrl handler" which is the analogue to a signal handler. * It must be tested how ncurses/win32 and PDCurses/win32a behaves in this regard. PDCurses/win32a is still actively maintained, so we can also patch its source base. * See #4 --- src/interface-curses.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/interface-curses.cpp b/src/interface-curses.cpp index 9114422..41f3e45 100644 --- a/src/interface-curses.cpp +++ b/src/interface-curses.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -30,10 +31,6 @@ #include #include -#ifdef G_OS_UNIX -#include -#endif - #include #ifdef HAVE_TIGETSTR @@ -60,6 +57,17 @@ #include "interface.h" #include "interface-curses.h" +#ifdef HAVE_WINDOWS_H +/* here it shouldn't cause conflicts with other headers */ +#include + +/* + * MinGW headers define an `interface` macro to work around + * Objective C issues + */ +#undef interface +#endif + /** * Whether we have PDCurses-only routines: * Could be 0, even on PDCurses @@ -95,8 +103,33 @@ namespace SciTECO { extern "C" { static void scintilla_notify(Scintilla *sci, int idFrom, void *notify, void *user_data); + +#ifdef PDCURSES_WIN32 + +/** + * This handler is the Windows-analogue of a signal + * handler. MinGW provides signal(), but it's not + * reliable. + * This may also be used to handle CTRL_CLOSE_EVENTs. + * NOTE: Unlike signal handlers, this is executed in a + * separate thread. + */ +static BOOL WINAPI +console_ctrl_handler(DWORD type) +{ + switch (type) { + case CTRL_C_EVENT: + sigint_occurred = TRUE; + return TRUE; + } + + return FALSE; } +#endif + +} /* extern "C" */ + #define UNNAMED_FILE "(Unnamed)" /** @@ -120,6 +153,16 @@ ViewCurses::initialize_impl(void) void InterfaceCurses::main_impl(int &argc, char **&argv) { + /* + * We must register this handler to handle + * asynchronous interruptions via CTRL+C + * reliably. The signal handler we already + * have won't do. + */ +#ifdef PDCURSES_WIN32 + SetConsoleCtrlHandler(console_ctrl_handler, TRUE); +#endif + /* * Make sure we have a string for the info line * even if info_update() is never called. @@ -720,6 +763,20 @@ event_loop_iter() { int key; + /* + * On PDCurses/win32, raw() and cbreak() does + * not disable and enable CTRL+C handling properly. + * Since I don't want to patch PDCurses/win32, + * we do this manually here. + * NOTE: This exploits the fact that PDCurses uses + * STD_INPUT_HANDLE internally! + */ +#ifdef PDCURSES_WIN32 + HANDLE console_hnd = GetStdHandle(STD_INPUT_HANDLE); + DWORD console_mode; + GetConsoleMode(console_hnd, &console_mode); +#endif + /* * Setting function key processing is important * on Unix Curses, as ESCAPE is handled as the beginning @@ -730,10 +787,16 @@ event_loop_iter() /* no special handling */ raw(); +#ifdef PDCURSES_WIN32 + SetConsoleMode(console_hnd, console_mode & ~ENABLE_PROCESSED_INPUT); +#endif key = wgetch(interface.cmdline_window); /* allow asynchronous interruptions on */ sigint_occurred = FALSE; cbreak(); +#ifdef PDCURSES_WIN32 + SetConsoleMode(console_hnd, console_mode | ENABLE_PROCESSED_INPUT); +#endif if (key == ERR) return; -- cgit v1.2.3