conhost: Use message window to return a window for windowless consoles.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38640
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-08-17 12:29:23 +02:00 committed by Alexandre Julliard
parent 365e99c022
commit da86e50e29
4 changed files with 60 additions and 23 deletions

View File

@ -4355,6 +4355,7 @@ static void test_pseudo_console_child(HANDLE input, HANDLE output)
CONSOLE_SCREEN_BUFFER_INFO sb_info;
CONSOLE_CURSOR_INFO cursor_info;
DWORD mode;
HWND hwnd;
BOOL ret;
ret = GetConsoleMode(input, &mode);
@ -4408,6 +4409,9 @@ static void test_pseudo_console_child(HANDLE input, HANDLE output)
ok(cursor_info.dwSize == 25, "dwSize = %u\n", cursor_info.dwSize);
ok(cursor_info.bVisible == TRUE, "bVisible = %x\n", cursor_info.bVisible);
hwnd = GetConsoleWindow();
ok(IsWindow(hwnd), "no console window\n");
test_console_title();
test_WriteConsoleInputW(input);
}

View File

@ -349,7 +349,7 @@ static void update_output( struct screen_buffer *screen_buffer, RECT *rect )
TRACE( "%s\n", wine_dbgstr_rect( rect ));
if (screen_buffer->console->win)
if (screen_buffer->console->window)
{
update_window_region( screen_buffer->console, rect );
return;
@ -2529,6 +2529,7 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
TRACE( "get window\n" );
if (in_size || *out_size != sizeof(*result)) return STATUS_INVALID_PARAMETER;
if (!(result = alloc_ioctl_buffer( sizeof(*result )))) return STATUS_NO_MEMORY;
if (!console->win) init_message_window( console );
*result = condrv_handle( console->win );
return STATUS_SUCCESS;
}
@ -2664,7 +2665,6 @@ static int main_loop( struct console *console, HANDLE signal )
unsigned short signal_id;
IO_STATUS_BLOCK signal_io;
NTSTATUS status;
BOOL pump_msgs;
DWORD res;
if (signal)
@ -2680,11 +2680,10 @@ static int main_loop( struct console *console, HANDLE signal )
wait_handles[wait_cnt++] = console->server;
if (signal) wait_handles[wait_cnt++] = signal_event;
if (console->input_thread) wait_handles[wait_cnt++] = console->input_thread;
pump_msgs = console->win != NULL;
for (;;)
{
if (pump_msgs)
if (console->win)
res = MsgWaitForMultipleObjects( wait_cnt, wait_handles, FALSE, INFINITE, QS_ALLINPUT );
else
res = WaitForMultipleObjects( wait_cnt, wait_handles, FALSE, INFINITE );

View File

@ -131,6 +131,7 @@ struct screen_buffer
};
BOOL init_window( struct console *console );
void init_message_window( struct console *console );
void update_window_region( struct console *console, const RECT *update );
void update_window_config( struct console *console, BOOL delay );

View File

@ -429,7 +429,7 @@ static void fill_mem_dc( struct console *console, const RECT *update )
/* set a new position for the cursor */
static void update_window_cursor( struct console *console )
{
if (console->win != GetFocus() || !console->active->cursor_visible) return;
if (!console->active->cursor_visible || console->win != GetFocus()) return;
SetCaretPos( (get_bounded_cursor_x( console->active ) - console->active->win.left) * console->active->font.width,
(console->active->cursor_y - console->active->win.top) * console->active->font.height );
@ -2143,15 +2143,18 @@ static LRESULT window_create( HWND hwnd, const CREATESTRUCTW *create )
SetWindowLongPtrW( hwnd, 0, (DWORD_PTR)console );
console->win = hwnd;
sys_menu = GetSystemMenu( hwnd, FALSE );
if (!sys_menu) return 0;
console->window->popup_menu = CreatePopupMenu();
if (!console->window->popup_menu) return 0;
if (console->window)
{
sys_menu = GetSystemMenu( hwnd, FALSE );
if (!sys_menu) return 0;
console->window->popup_menu = CreatePopupMenu();
if (!console->window->popup_menu) return 0;
fill_menu( sys_menu, TRUE );
fill_menu( console->window->popup_menu, FALSE );
fill_menu( sys_menu, TRUE );
fill_menu( console->window->popup_menu, FALSE );
console->window->mem_dc = CreateCompatibleDC( 0 );
console->window->mem_dc = CreateCompatibleDC( 0 );
}
return 0;
}
@ -2171,7 +2174,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
case WM_TIMER:
case WM_UPDATE_CONFIG:
if (console->window->update_state == UPDATE_PENDING)
if (console->window && console->window->update_state == UPDATE_PENDING)
update_window( console );
break;
@ -2179,6 +2182,8 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
{
PAINTSTRUCT ps;
if (!console->window) break;
BeginPaint( console->win, &ps );
BitBlt( ps.hdc, 0, 0,
(console->active->win.right - console->active->win.left + 1) * console->active->font.width,
@ -2193,6 +2198,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
}
case WM_SHOWWINDOW:
if (!console->window) break;
if (wparam)
update_window( console );
else
@ -2204,7 +2210,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
case WM_KEYDOWN:
case WM_KEYUP:
if (console->window->in_selection)
if (console->window && console->window->in_selection)
handle_selection_key( console, msg == WM_KEYDOWN, wparam, lparam );
else
record_key_input( console, msg == WM_KEYDOWN, wparam, lparam );
@ -2216,7 +2222,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_LBUTTONDOWN:
if (console->window->quick_edit || console->window->in_selection)
if (console->window && (console->window->quick_edit || console->window->in_selection))
{
if (console->window->in_selection)
update_selection( console, 0 );
@ -2241,7 +2247,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_MOUSEMOVE:
if (console->window->quick_edit || console->window->in_selection)
if (console->window && (console->window->quick_edit || console->window->in_selection))
{
if (GetCapture() == console->win && console->window->in_selection &&
(wparam & MK_LBUTTON))
@ -2257,7 +2263,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_LBUTTONUP:
if (console->window->quick_edit || console->window->in_selection)
if (console->window && (console->window->quick_edit || console->window->in_selection))
{
if (GetCapture() == console->win && console->window->in_selection)
{
@ -2273,7 +2279,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_RBUTTONDOWN:
if ((wparam & (MK_CONTROL|MK_SHIFT)) == console->window->menu_mask)
if (console->window && (wparam & (MK_CONTROL|MK_SHIFT)) == console->window->menu_mask)
{
POINT pt;
pt.x = (short)LOWORD(lparam);
@ -2304,7 +2310,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_SETFOCUS:
if (console->active->cursor_visible)
if (console->window && console->active->cursor_visible)
{
CreateCaret( console->win, console->window->cursor_bitmap,
console->active->font.width, console->active->font.height );
@ -2313,12 +2319,12 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_KILLFOCUS:
if (console->active->cursor_visible)
if (console->window && console->active->cursor_visible)
DestroyCaret();
break;
case WM_SIZE:
if (console->window->update_state != UPDATE_BUSY)
if (console->window && console->window->update_state != UPDATE_BUSY)
resize_window( console,
max( LOWORD(lparam) / console->active->font.width, 20 ),
max( HIWORD(lparam) / console->active->font.height, 20 ));
@ -2329,6 +2335,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
int win_width = console->active->win.right - console->active->win.left + 1;
int x = console->active->win.left;
if (!console->window) break;
switch (LOWORD(wparam))
{
case SB_PAGEUP: x -= 8; break;
@ -2360,6 +2367,8 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
int win_height = console->active->win.bottom - console->active->win.top + 1;
int y = console->active->win.top;
if (!console->window) break;
if (msg == WM_MOUSEWHEEL)
{
UINT scroll_lines = 3;
@ -2391,6 +2400,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
}
case WM_SYSCOMMAND:
if (!console->window) break;
switch (wparam)
{
case IDS_DEFAULT:
@ -2405,6 +2415,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_COMMAND:
if (!console->window) break;
switch (wparam)
{
case IDS_DEFAULT:
@ -2447,7 +2458,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
break;
case WM_INITMENUPOPUP:
if (!HIWORD(lparam)) return DefWindowProcW( hwnd, msg, wparam, lparam );
if (!console->window || !HIWORD(lparam)) return DefWindowProcW( hwnd, msg, wparam, lparam );
set_menu_details( console, GetSystemMenu(console->win, FALSE) );
break;
@ -2462,7 +2473,7 @@ void update_window_config( struct console *console, BOOL delay )
{
const int delay_timeout = 50;
if (!console->win || console->window->update_state != UPDATE_NONE) return;
if (!console->window || console->window->update_state != UPDATE_NONE) return;
console->window->update_state = UPDATE_PENDING;
if (delay)
SetTimer( console->win, 1, delay_timeout, NULL );
@ -2536,3 +2547,25 @@ BOOL init_window( struct console *console )
apply_config( console, &config );
return TRUE;
}
void init_message_window( struct console *console )
{
WNDCLASSW wndclass;
wndclass.style = CS_DBLCLKS;
wndclass.lpfnWndProc = window_proc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof(DWORD_PTR);
wndclass.hInstance = GetModuleHandleW( NULL );
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = GetStockObject( BLACK_BRUSH );
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = L"WineConsoleClass";
RegisterClassW(&wndclass);
CreateWindowW( wndclass.lpszClassName, NULL,
WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|
WS_MAXIMIZEBOX|WS_HSCROLL|WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, HWND_MESSAGE, 0, wndclass.hInstance, console );
}