Module: wine Branch: master Commit: 4225ec994e64f365b0b093609a3343c0ae1987f0 URL: https://source.winehq.org/git/wine.git/?a=commit;h=4225ec994e64f365b0b093609...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Aug 25 14:52:25 2020 +0200
conhost: Implement IOCTL_CONDRV_WRITE_INPUT.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
programs/conhost/conhost.c | 54 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index c658deb1cf..525ca9058e 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -45,7 +45,9 @@ struct console { HANDLE server; /* console server handle */ unsigned int mode; /* input mode */ - unsigned int recnum; /* number of input records */ + INPUT_RECORD *records; /* input records */ + unsigned int record_count; /* number of input records */ + unsigned int record_size; /* size of input records buffer */ WCHAR *title; /* console title */ size_t title_len; /* length of console title */ struct history_line **history; /* lines history */ @@ -73,6 +75,49 @@ static void *alloc_ioctl_buffer( size_t size ) return ioctl_buffer; }
+/* add input events to a console input queue */ +static NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *records, + unsigned int count ) +{ + TRACE( "%u\n", count ); + + if (!count) return STATUS_SUCCESS; + if (console->record_count + count > console->record_size) + { + INPUT_RECORD *new_rec; + if (!(new_rec = realloc( console->records, (console->record_size * 2 + count) * sizeof(INPUT_RECORD) ))) + return STATUS_NO_MEMORY; + console->records = new_rec; + console->record_size = console->record_size * 2 + count; + } + memcpy( console->records + console->record_count, records, count * sizeof(INPUT_RECORD) ); + + if (console->mode & ENABLE_PROCESSED_INPUT) + { + 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)) + { + if (i != count - 1) + memcpy( &console->records[console->record_count + i], + &console->records[console->record_count + i + 1], + (count - i - 1) * sizeof(INPUT_RECORD) ); + count--; + if (records[i].Event.KeyEvent.bKeyDown) + { + FIXME("CTRL C\n"); + } + } + else i++; + } + } + console->record_count += count; + return STATUS_SUCCESS; +} + static NTSTATUS set_console_title( struct console *console, const WCHAR *in_title, size_t size ) { WCHAR *title = NULL; @@ -111,6 +156,10 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code, TRACE( "set %x mode\n", console->mode ); return STATUS_SUCCESS;
+ case IOCTL_CONDRV_WRITE_INPUT: + if (in_size % sizeof(INPUT_RECORD) || *out_size) return STATUS_INVALID_PARAMETER; + return write_console_input( console, in_data, in_size / sizeof(INPUT_RECORD) ); + case IOCTL_CONDRV_GET_INPUT_INFO: { struct condrv_input_info *info; @@ -124,7 +173,7 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code, info->input_cp = console->input_cp; info->output_cp = console->output_cp; info->win = console->win; - info->input_count = console->recnum; + info->input_count = console->record_count; return STATUS_SUCCESS; }
@@ -221,6 +270,7 @@ static NTSTATUS process_console_ioctls( struct console *console ) { req->handle = wine_server_obj_handle( console->server ); req->status = status; + req->signal = console->record_count != 0; wine_server_add_data( req, ioctl_buffer, out_size ); wine_server_set_reply( req, ioctl_buffer, ioctl_buffer_size ); status = wine_server_call( req );