Jacek Caban : conhost: Implement IOCTL_CONDRV_WRITE_INPUT.

Alexandre Julliard julliard at winehq.org
Wed Aug 26 15:24:44 CDT 2020


Module: wine
Branch: master
Commit: 4225ec994e64f365b0b093609a3343c0ae1987f0
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=4225ec994e64f365b0b093609a3343c0ae1987f0

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Aug 25 14:52:25 2020 +0200

conhost: Implement IOCTL_CONDRV_WRITE_INPUT.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 );




More information about the wine-cvs mailing list