aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/interface-curses.cpp
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-20 15:00:12 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-22 04:09:32 +0200
commitdb82e1be3a650225f2902927d034c7ff434b513d (patch)
tree84931c6b2e5097ea089138528d4ba9b652fbdbf6 /src/interface-curses.cpp
parent8101cec729c07fd5bdeda70c12dbb43a2383cbe8 (diff)
downloadsciteco-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.cpp71
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;