Jacek Caban : conhost: Import mouse event handling from wineconsole.
Alexandre Julliard
julliard at winehq.org
Fri Oct 9 16:00:46 CDT 2020
Module: wine
Branch: master
Commit: 91be31b28ad5ae4852d2cc3cc3bcfc3e2ee01895
URL: https://source.winehq.org/git/wine.git/?a=commit;h=91be31b28ad5ae4852d2cc3cc3bcfc3e2ee01895
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Oct 9 17:27:48 2020 +0200
conhost: Import mouse event handling from wineconsole.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
programs/conhost/window.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 146 insertions(+)
diff --git a/programs/conhost/window.c b/programs/conhost/window.c
index 863d3e6ee1..b4891fb67d 100644
--- a/programs/conhost/window.c
+++ b/programs/conhost/window.c
@@ -840,6 +840,15 @@ static void update_console_font( struct console *console, const WCHAR *font,
ERR( "Couldn't find a decent font" );
}
+/* get a cell from a relative coordinate in window (takes into account the scrolling) */
+static COORD get_cell( struct console *console, LPARAM lparam )
+{
+ COORD c;
+ c.X = console->active->win.left + (short)LOWORD(lparam) / console->active->font.width;
+ c.Y = console->active->win.left + (short)HIWORD(lparam) / console->active->font.height;
+ return c;
+}
+
/* get the console bit mask equivalent to the VK_ status in key state */
static DWORD get_ctrl_state( BYTE *key_state)
{
@@ -1091,6 +1100,29 @@ static void record_key_input( struct console *console, BOOL down, WPARAM wparam,
write_console_input( console, &ir, 1, TRUE );
}
+static void record_mouse_input( struct console *console, COORD c, WPARAM wparam, DWORD event )
+{
+ BYTE key_state[256];
+ INPUT_RECORD ir;
+
+ /* MOUSE_EVENTs shouldn't be sent unless ENABLE_MOUSE_INPUT is active */
+ if (!(console->mode & ENABLE_MOUSE_INPUT)) return;
+
+ ir.EventType = MOUSE_EVENT;
+ ir.Event.MouseEvent.dwMousePosition = c;
+ ir.Event.MouseEvent.dwButtonState = 0;
+ if (wparam & MK_LBUTTON) ir.Event.MouseEvent.dwButtonState |= FROM_LEFT_1ST_BUTTON_PRESSED;
+ if (wparam & MK_MBUTTON) ir.Event.MouseEvent.dwButtonState |= FROM_LEFT_2ND_BUTTON_PRESSED;
+ if (wparam & MK_RBUTTON) ir.Event.MouseEvent.dwButtonState |= RIGHTMOST_BUTTON_PRESSED;
+ if (wparam & MK_CONTROL) ir.Event.MouseEvent.dwButtonState |= LEFT_CTRL_PRESSED;
+ if (wparam & MK_SHIFT) ir.Event.MouseEvent.dwButtonState |= SHIFT_PRESSED;
+ if (event == MOUSE_WHEELED) ir.Event.MouseEvent.dwButtonState |= wparam & 0xFFFF0000;
+ ir.Event.MouseEvent.dwControlKeyState = get_ctrl_state( key_state );
+ ir.Event.MouseEvent.dwEventFlags = event;
+
+ write_console_input( console, &ir, 1, TRUE );
+}
+
static void apply_config( struct console *console, const struct console_config *config )
{
if (console->active->width != config->sb_width || console->active->height != config->sb_height)
@@ -1157,6 +1189,17 @@ static void apply_config( struct console *console, const struct console_config *
update_window( console );
}
+/* grays / ungrays the menu items according to their state */
+static void set_menu_details( struct console *console, HMENU menu )
+{
+ EnableMenuItem( menu, IDS_COPY, MF_BYCOMMAND |
+ (console->window->in_selection ? MF_ENABLED : MF_GRAYED) );
+ EnableMenuItem( menu, IDS_PASTE, MF_BYCOMMAND |
+ (IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED) );
+ EnableMenuItem( menu, IDS_SCROLL, MF_BYCOMMAND | MF_GRAYED );
+ EnableMenuItem( menu, IDS_SEARCH, MF_BYCOMMAND | MF_GRAYED );
+}
+
static BOOL fill_menu( HMENU menu, BOOL sep )
{
HINSTANCE module = GetModuleHandleW( NULL );
@@ -1244,6 +1287,7 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
console->active->win.left * console->active->font.width,
console->active->win.top * console->active->font.height,
SRCCOPY );
+ if (console->window->in_selection) update_selection( console, ps.hdc );
EndPaint( console->win, &ps );
break;
}
@@ -1261,6 +1305,108 @@ static LRESULT WINAPI window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
record_key_input( console, msg == WM_SYSKEYDOWN, wparam, lparam );
break;
+ case WM_LBUTTONDOWN:
+ if (console->window->quick_edit || console->window->in_selection)
+ {
+ if (console->window->in_selection)
+ update_selection( console, 0 );
+
+ if (console->window->quick_edit && console->window->in_selection)
+ {
+ console->window->in_selection = FALSE;
+ }
+ else
+ {
+ console->window->selection_end = get_cell( console, lparam );
+ console->window->selection_start = console->window->selection_end;
+ SetCapture( console->win );
+ update_selection( console, 0 );
+ console->window->in_selection = TRUE;
+ }
+ }
+ else
+ {
+ record_mouse_input( console, get_cell(console, lparam), wparam, 0 );
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ if (console->window->quick_edit || console->window->in_selection)
+ {
+ if (GetCapture() == console->win && console->window->in_selection &&
+ (wparam & MK_LBUTTON))
+ {
+ move_selection( console, console->window->selection_start,
+ get_cell(console, lparam) );
+ }
+ }
+ else
+ {
+ record_mouse_input( console, get_cell(console, lparam), wparam, MOUSE_MOVED );
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ if (console->window->quick_edit || console->window->in_selection)
+ {
+ if (GetCapture() == console->win && console->window->in_selection)
+ {
+ move_selection( console, console->window->selection_start,
+ get_cell(console, lparam) );
+ ReleaseCapture();
+ }
+ }
+ else
+ {
+ record_mouse_input( console, get_cell(console, lparam), wparam, 0 );
+ }
+ break;
+
+ case WM_RBUTTONDOWN:
+ if ((wparam & (MK_CONTROL|MK_SHIFT)) == console->window->menu_mask)
+ {
+ POINT pt;
+ pt.x = (short)LOWORD(lparam);
+ pt.y = (short)HIWORD(lparam);
+ ClientToScreen( hwnd, &pt );
+ set_menu_details( console, console->window->popup_menu );
+ TrackPopupMenu( console->window->popup_menu, TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON,
+ pt.x, pt.y, 0, hwnd, NULL );
+ }
+ else
+ {
+ record_mouse_input( console, get_cell(console, lparam), wparam, 0 );
+ }
+ break;
+
+ case WM_RBUTTONUP:
+ /* no need to track for rbutton up when opening the popup... the event will be
+ * swallowed by TrackPopupMenu */
+ case WM_MBUTTONDOWN:
+ case WM_MBUTTONUP:
+ record_mouse_input( console, get_cell(console, lparam), wparam, 0 );
+ break;
+
+ case WM_LBUTTONDBLCLK:
+ case WM_MBUTTONDBLCLK:
+ case WM_RBUTTONDBLCLK:
+ record_mouse_input( console, get_cell(console, lparam), wparam, DOUBLE_CLICK );
+ break;
+
+ case WM_SETFOCUS:
+ if (console->active->cursor_visible)
+ {
+ CreateCaret( console->win, console->window->cursor_bitmap,
+ console->active->font.width, console->active->font.height );
+ update_window_cursor( console );
+ }
+ break;
+
+ case WM_KILLFOCUS:
+ if (console->active->cursor_visible)
+ DestroyCaret();
+ break;
+
default:
return DefWindowProcW( hwnd, msg, wparam, lparam );
}
More information about the wine-cvs
mailing list