diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-06-20 15:00:12 +0200 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2015-06-22 04:09:32 +0200 |
commit | db82e1be3a650225f2902927d034c7ff434b513d (patch) | |
tree | 84931c6b2e5097ea089138528d4ba9b652fbdbf6 /src/interface-curses.cpp | |
parent | 8101cec729c07fd5bdeda70c12dbb43a2383cbe8 (diff) | |
download | sciteco-db82e1be3a650225f2902927d034c7ff434b513d.tar.gz |
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
Diffstat (limited to 'src/interface-curses.cpp')
-rw-r--r-- | src/interface-curses.cpp | 71 |
1 files changed, 67 insertions, 4 deletions
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 <stdio.h> #include <stdlib.h> #include <stdarg.h> +#include <unistd.h> #include <locale.h> #include <errno.h> @@ -30,10 +31,6 @@ #include <glib/gprintf.h> #include <glib/gstdio.h> -#ifdef G_OS_UNIX -#include <unistd.h> -#endif - #include <curses.h> #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 <windows.h> + +/* + * 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)" /** @@ -121,6 +154,16 @@ 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. */ @@ -721,6 +764,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 * of a escape sequence when terminal emulators are @@ -730,10 +787,16 @@ event_loop_iter() /* no special <CTRL/C> handling */ raw(); +#ifdef PDCURSES_WIN32 + SetConsoleMode(console_hnd, console_mode & ~ENABLE_PROCESSED_INPUT); +#endif key = wgetch(interface.cmdline_window); /* allow asynchronous interruptions on <CTRL/C> */ sigint_occurred = FALSE; cbreak(); +#ifdef PDCURSES_WIN32 + SetConsoleMode(console_hnd, console_mode | ENABLE_PROCESSED_INPUT); +#endif if (key == ERR) return; |