summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/libw32c.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2013-10-30 21:59:59 +0100
committerAdam Borowski <kilobyte@angband.pl>2013-11-25 23:47:49 +0100
commit5f077547fa1719e85543b7c6734a251bd364a680 (patch)
tree4bf512805eeaacfeb997ea487e8ea643f32913e4 /crawl-ref/source/libw32c.cc
parent836b35dd65790f235e782529e43b8fd3f7bfd798 (diff)
downloadcrawl-ref-5f077547fa1719e85543b7c6734a251bd364a680.tar.gz
crawl-ref-5f077547fa1719e85543b7c6734a251bd364a680.zip
Allow graceful shutdown rather than a forced save (win32 console).
This injects a fake key code into the input stream, making the syscall return. The pseudo-signal handler thread will then wait forever (for a value of "forever" of 15 seconds).
Diffstat (limited to 'crawl-ref/source/libw32c.cc')
-rw-r--r--crawl-ref/source/libw32c.cc22
1 files changed, 22 insertions, 0 deletions
diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc
index c7b11c8c7f..4dbffcc58f 100644
--- a/crawl-ref/source/libw32c.cc
+++ b/crawl-ref/source/libw32c.cc
@@ -270,6 +270,22 @@ static void _set_string_input(bool value)
FlushConsoleInputBuffer(inbuf);
}
+// Fake the user pressing Esc to break out of wait-for-input loops.
+// Just one should be enough as we check the seen_hups flag, we just
+// need to interrupt the syscall.
+void w32_insert_escape()
+{
+ INPUT_RECORD esc;
+ esc.EventType = KEY_EVENT;
+ esc.Event.KeyEvent.bKeyDown = TRUE;
+ esc.Event.KeyEvent.wRepeatCount = 1;
+ esc.Event.KeyEvent.wVirtualKeyCode = VK_ESCAPE;
+ // .wVirtualScanCode ?
+ esc.Event.KeyEvent.uChar.UnicodeChar = ESCAPE;
+ esc.Event.KeyEvent.dwControlKeyState = 0;
+ WriteConsoleInputW(inbuf, &esc, 1, nullptr);
+}
+
#ifdef TARGET_COMPILER_MINGW
static void install_sighandlers()
{
@@ -779,6 +795,9 @@ int getch_ck(void)
bool waiting_for_event = true;
while (waiting_for_event)
{
+ if (crawl_state.seen_hups)
+ return ESCAPE;
+
if (ReadConsoleInputW(inbuf, &ir, 1, &nread) == 0)
fputs("Error in ReadConsoleInputW()!", stderr);
if (nread > 0)
@@ -830,6 +849,9 @@ int getchk(void)
bool kbhit()
{
+ if (crawl_state.seen_hups)
+ return 1;
+
INPUT_RECORD ir[10];
DWORD read_count = 0;
PeekConsoleInputW(inbuf, ir, ARRAYSZ(ir), &read_count);