conhost: Implement IOCTL_CONDRV_READ_INPUT.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b75ae8c31e
commit
e703e2da39
|
@ -3968,6 +3968,7 @@ static void test_pseudo_console_child(HANDLE input)
|
||||||
ok(ret, "SetConsoleMode failed: %u\n", GetLastError());
|
ok(ret, "SetConsoleMode failed: %u\n", GetLastError());
|
||||||
|
|
||||||
test_console_title();
|
test_console_title();
|
||||||
|
test_WriteConsoleInputW(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI read_pipe_proc( void *handle )
|
static DWORD WINAPI read_pipe_proc( void *handle )
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct console
|
||||||
INPUT_RECORD *records; /* input records */
|
INPUT_RECORD *records; /* input records */
|
||||||
unsigned int record_count; /* number of input records */
|
unsigned int record_count; /* number of input records */
|
||||||
unsigned int record_size; /* size of input records buffer */
|
unsigned int record_size; /* size of input records buffer */
|
||||||
|
size_t pending_read; /* size of pending read buffer */
|
||||||
WCHAR *title; /* console title */
|
WCHAR *title; /* console title */
|
||||||
size_t title_len; /* length of console title */
|
size_t title_len; /* length of console title */
|
||||||
struct history_line **history; /* lines history */
|
struct history_line **history; /* lines history */
|
||||||
|
@ -75,6 +76,36 @@ static void *alloc_ioctl_buffer( size_t size )
|
||||||
return ioctl_buffer;
|
return ioctl_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS read_console_input( struct console *console, size_t out_size )
|
||||||
|
{
|
||||||
|
size_t count = min( out_size / sizeof(INPUT_RECORD), console->record_count );
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
TRACE("count %u\n", count);
|
||||||
|
|
||||||
|
SERVER_START_REQ( get_next_console_request )
|
||||||
|
{
|
||||||
|
req->handle = wine_server_obj_handle( console->server );
|
||||||
|
req->signal = count < console->record_count;
|
||||||
|
req->read = 1;
|
||||||
|
req->status = STATUS_SUCCESS;
|
||||||
|
wine_server_add_data( req, console->records, count * sizeof(*console->records) );
|
||||||
|
status = wine_server_call( req );
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
ERR( "failed: %#x\n", status );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < console->record_count)
|
||||||
|
memmove( console->records, console->records + count,
|
||||||
|
(console->record_count - count) * sizeof(*console->records) );
|
||||||
|
console->record_count -= count;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* add input events to a console input queue */
|
/* add input events to a console input queue */
|
||||||
static NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *records,
|
static NTSTATUS write_console_input( struct console *console, const INPUT_RECORD *records,
|
||||||
unsigned int count )
|
unsigned int count )
|
||||||
|
@ -115,6 +146,11 @@ static NTSTATUS write_console_input( struct console *console, const INPUT_RECORD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console->record_count += count;
|
console->record_count += count;
|
||||||
|
if (count && console->pending_read)
|
||||||
|
{
|
||||||
|
read_console_input( console, console->pending_read );
|
||||||
|
console->pending_read = 0;
|
||||||
|
}
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +192,23 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
|
||||||
TRACE( "set %x mode\n", console->mode );
|
TRACE( "set %x mode\n", console->mode );
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
case IOCTL_CONDRV_READ_INPUT:
|
||||||
|
{
|
||||||
|
unsigned int blocking;
|
||||||
|
NTSTATUS status;
|
||||||
|
if (in_size && in_size != sizeof(blocking)) return STATUS_INVALID_PARAMETER;
|
||||||
|
blocking = in_size && *(unsigned int *)in_data;
|
||||||
|
if (blocking && !console->record_count && *out_size)
|
||||||
|
{
|
||||||
|
TRACE( "pending read" );
|
||||||
|
console->pending_read = *out_size;
|
||||||
|
return STATUS_PENDING;
|
||||||
|
}
|
||||||
|
status = read_console_input( console, *out_size );
|
||||||
|
*out_size = 0;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
case IOCTL_CONDRV_WRITE_INPUT:
|
case IOCTL_CONDRV_WRITE_INPUT:
|
||||||
if (in_size % sizeof(INPUT_RECORD) || *out_size) return STATUS_INVALID_PARAMETER;
|
if (in_size % sizeof(INPUT_RECORD) || *out_size) return STATUS_INVALID_PARAMETER;
|
||||||
return write_console_input( console, in_data, in_size / sizeof(INPUT_RECORD) );
|
return write_console_input( console, in_data, in_size / sizeof(INPUT_RECORD) );
|
||||||
|
|
Loading…
Reference in New Issue