The first intend of this serie is that CUI app in non processed input mode should not die when using the ctrl-\ key stroke.
This series: - implements ctrl-pause/break in conhost.exe (in processed mode) by generating the proper console event - maps for unix-console ctrl-\ into a ctrl-pause/break key stroke.
Code change is relatively small, and fixes an annoying behavior in unix consoles (see bug report).
The series could have been a bit smaller by not adding ctrl-break support in user32 console, but: - it's cleaner that way - it still requires the server changes (which may be perhaps the most questionnable here, esp. the termios change).
So a valid (IMO) candidate for 8.0.
From: Eric Pouech eric.pouech@gmail.com
Note: this patch should be extended by adding insertion of the CTRL_BREAK_EVENT into processes' crtl handler (as it's done for CTRL_C_EVENT).
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/conhost/conhost.c | 31 +++++++++++++++++++++++++++---- server/console.c | 8 +++++--- 2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 769f998f404..5099f2b6610 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -1462,6 +1462,29 @@ static NTSTATUS read_console( struct console *console, unsigned int ioctl, size_ return process_console_input( console ); }
+static BOOL map_to_ctrlevent( struct console *console, const INPUT_RECORD *record, + unsigned int* event) +{ + if (record->EventType == KEY_EVENT) + { + if (record->Event.KeyEvent.uChar.UnicodeChar == 'C' - 64 && + !(record->Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)) + { + *event = CTRL_C_EVENT; + return TRUE; + } + /* we want to get ctrl-pause/break, but it's already translated by user32 into VK_CANCEL */ + if (record->Event.KeyEvent.uChar.UnicodeChar == 0 && + record->Event.KeyEvent.wVirtualKeyCode == VK_CANCEL && + record->Event.KeyEvent.dwControlKeyState == LEFT_CTRL_PRESSED) + { + *event = CTRL_BREAK_EVENT; + return TRUE; + } + } + return FALSE; +} + /* add input events to a console input queue */ NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *records, unsigned int count, BOOL flush ) @@ -1484,9 +1507,9 @@ NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *recor unsigned int i = 0; while (i < count) { - if (records[i].EventType == KEY_EVENT && - records[i].Event.KeyEvent.uChar.UnicodeChar == 'C' - 64 && - !(records[i].Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)) + unsigned int event; + + if (map_to_ctrlevent(console, &records[i], &event)) { if (i != count - 1) memcpy( &console->records[console->record_count + i], @@ -1498,7 +1521,7 @@ NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *recor struct condrv_ctrl_event ctrl_event; IO_STATUS_BLOCK io;
- ctrl_event.event = CTRL_C_EVENT; + ctrl_event.event = event; ctrl_event.group_id = 0; NtDeviceIoControlFile( console->server, NULL, NULL, NULL, &io, IOCTL_CONDRV_CTRL_EVENT, &ctrl_event, sizeof(ctrl_event), NULL, 0 ); diff --git a/server/console.c b/server/console.c index 5f3f50d006f..34f8d09408f 100644 --- a/server/console.c +++ b/server/console.c @@ -694,14 +694,16 @@ static void propagate_console_signal( struct console *console, set_error( STATUS_INVALID_PARAMETER ); return; } - /* FIXME: should support the other events (like CTRL_BREAK) */ - if (sig != CTRL_C_EVENT) + switch (sig) { + case CTRL_C_EVENT: csi.signal = SIGINT; break; + case CTRL_BREAK_EVENT: csi.signal = SIGQUIT; break; + default: + /* FIXME: should support the other events */ set_error( STATUS_NOT_IMPLEMENTED ); return; } csi.console = console; - csi.signal = SIGINT; csi.group = group_id;
enum_processes(propagate_console_signal_cb, &csi);
From: Eric Pouech eric.pouech@gmail.com
Let conhost handle ctrl-\ instead of Unix tty, and pretend it's a ctrl-pause/break key stroke. This allows CUI application in processed input mode not to close upon ctrl-.
See https://bugs.winehq.org/show_bug.cgi?id=54141 for some details.
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/conhost/conhost.c | 6 ++++++ server/console.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 5099f2b6610..8990e975879 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -1777,6 +1777,12 @@ static DWORD WINAPI tty_input( void *param ) case 0x1b: i += process_input_escape( console, buf + i + 1, count - i - 1 ); break; + case 0x1c: /* map ctrl-\ unix-ism into ctrl-break/pause windows-ism for unix consoles */ + if (console->is_unix) + key_press( console, 0, VK_CANCEL, LEFT_CTRL_PRESSED ); + else + char_key_press( console, ch, 0 ); + break; case 0x7f: key_press( console, '\b', VK_BACK, 0 ); break; diff --git a/server/console.c b/server/console.c index 34f8d09408f..b64283baf4a 100644 --- a/server/console.c +++ b/server/console.c @@ -1183,7 +1183,7 @@ static void console_server_ioctl( struct fd *fd, ioctl_code_t code, struct async return; } term = server->termios; - term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN); + term.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); term.c_cflag &= ~(CSIZE | PARENB); term.c_cflag |= CS8;