Use the multitouch API. To disable system's defualt mouse emulation, set --native-touch=yes.
Unified · Split
| @@ -568,19 +568,29 @@ static void begin_dragging(struct vo_w32_state *w32) · 567 unmodified lines | |||
| 568 | mp_input_put_key(w32->input_ctx, MP_INPUT_RELEASE_ALL); | 568 | mp_input_put_key(w32->input_ctx, MP_INPUT_RELEASE_ALL); |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | static bool handle_mouse_down(struct vo_w32_state *w32, int btn, int x, int y) | 571 | // If native touch is enabled and the mouse event is emulated, ignore it. |
| 572 | // See: <https://learn.microsoft.com/en-us/windows/win32/tablet/ | ||
| 573 | // system-events-and-mouse-messages#distinguishing-pen-input-from-mouse-and-touch> | ||
| 574 | static bool should_ignore_mouse_event(const struct vo_w32_state *w32) | ||
| 572 | { | 575 | { |
| 576 | return w32->opts->native_touch && ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700); | ||
| 577 | } | ||
| 578 | |||
| 579 | static void handle_mouse_down(struct vo_w32_state *w32, int btn, int x, int y) | ||
| 580 | { | ||
| 581 | if (should_ignore_mouse_event(w32)) | ||
| 582 | return; | ||
| 573 | btn |= mod_state(w32); | 583 | btn |= mod_state(w32); |
| 574 | mp_input_put_key(w32->input_ctx, btn | MP_KEY_STATE_DOWN); | 584 | mp_input_put_key(w32->input_ctx, btn | MP_KEY_STATE_DOWN); |
| 575 | SetCapture(w32->window); | 585 | SetCapture(w32->window); |
| 576 | return false; | ||
| 577 | } | 586 | } |
| 578 | 587 | ||
| 579 | static void handle_mouse_up(struct vo_w32_state *w32, int btn) | 588 | static void handle_mouse_up(struct vo_w32_state *w32, int btn) |
| 580 | { | 589 | { |
| 590 | if (should_ignore_mouse_event(w32)) | ||
| 591 | return; | ||
| 581 | btn |= mod_state(w32); | 592 | btn |= mod_state(w32); |
| 582 | mp_input_put_key(w32->input_ctx, btn | MP_KEY_STATE_UP); | 593 | mp_input_put_key(w32->input_ctx, btn | MP_KEY_STATE_UP); |
| 583 | |||
| 584 | ReleaseCapture(); | 594 | ReleaseCapture(); |
| 585 | } | 595 | } |
| 586 | 596 | ||
| @@ -1315,6 +1325,19 @@ static void update_cursor_passthrough(const struct vo_w32_state *w32) · 728 unmodified lines | |||
| 1315 | } | 1325 | } |
| 1316 | } | 1326 | } |
| 1317 | 1327 | ||
| 1328 | static void update_native_touch(const struct vo_w32_state *w32) | ||
| 1329 | { | ||
| 1330 | if (w32->parent) | ||
| 1331 | return; | ||
| 1332 | |||
| 1333 | if (w32->opts->native_touch) { | ||
| 1334 | RegisterTouchWindow(w32->window, 0); | ||
| 1335 | } else { | ||
| 1336 | UnregisterTouchWindow(w32->window); | ||
| 1337 | mp_input_put_key(w32->input_ctx, MP_TOUCH_RELEASE_ALL); | ||
| 1338 | } | ||
| 1339 | } | ||
| 1340 | |||
| 1318 | static void set_ime_conversion_mode(const struct vo_w32_state *w32, DWORD mode) | 1341 | static void set_ime_conversion_mode(const struct vo_w32_state *w32, DWORD mode) |
| 1319 | { | 1342 | { |
| 1320 | if (w32->parent) | 1343 | if (w32->parent) |
| @@ -1615,14 +1638,14 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, · 294 unmodified lines | |||
| 1615 | if (x != w32->mouse_x || y != w32->mouse_y) { | 1638 | if (x != w32->mouse_x || y != w32->mouse_y) { |
| 1616 | w32->mouse_x = x; | 1639 | w32->mouse_x = x; |
| 1617 | w32->mouse_y = y; | 1640 | w32->mouse_y = y; |
| 1618 | mp_input_set_mouse_pos(w32->input_ctx, x, y); | 1641 | if (!should_ignore_mouse_event(w32)) |
| 1642 | mp_input_set_mouse_pos(w32->input_ctx, x, y); | ||
| 1619 | } | 1643 | } |
| 1620 | break; | 1644 | break; |
| 1621 | } | 1645 | } |
| 1622 | case WM_LBUTTONDOWN: | 1646 | case WM_LBUTTONDOWN: |
| 1623 | if (handle_mouse_down(w32, MP_MBTN_LEFT, GET_X_LPARAM(lParam), | 1647 | handle_mouse_down(w32, MP_MBTN_LEFT, GET_X_LPARAM(lParam), |
| 1624 | GET_Y_LPARAM(lParam))) | 1648 | GET_Y_LPARAM(lParam)); |
| 1625 | return 0; | ||
| 1626 | break; | 1649 | break; |
| 1627 | case WM_LBUTTONUP: | 1650 | case WM_LBUTTONUP: |
| 1628 | handle_mouse_up(w32, MP_MBTN_LEFT); | 1651 | handle_mouse_up(w32, MP_MBTN_LEFT); |
| @@ -1713,6 +1736,26 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, · 84 unmodified lines | |||
| 1713 | case WM_SHOWMENU: | 1736 | case WM_SHOWMENU: |
| 1714 | mp_win32_menu_show(w32->menu_ctx, w32->window); | 1737 | mp_win32_menu_show(w32->menu_ctx, w32->window); |
| 1715 | break; | 1738 | break; |
| 1739 | case WM_TOUCH: { | ||
| 1740 | UINT count = LOWORD(wParam); | ||
| 1741 | TOUCHINPUT *inputs = talloc_array_ptrtype(NULL, inputs, count); | ||
| 1742 | if (GetTouchInputInfo((HTOUCHINPUT)lParam, count, inputs, sizeof(TOUCHINPUT))) { | ||
| 1743 | for (UINT i = 0; i < count; i++) { | ||
| 1744 | TOUCHINPUT *ti = &inputs[i]; | ||
| 1745 | POINT pt = {TOUCH_COORD_TO_PIXEL(ti->x), TOUCH_COORD_TO_PIXEL(ti->y)}; | ||
| 1746 | ScreenToClient(w32->window, &pt); | ||
| 1747 | if (ti->dwFlags & TOUCHEVENTF_DOWN) | ||
| 1748 | mp_input_add_touch_point(w32->input_ctx, ti->dwID, pt.x, pt.y); | ||
| 1749 | if (ti->dwFlags & TOUCHEVENTF_MOVE) | ||
| 1750 | mp_input_update_touch_point(w32->input_ctx, ti->dwID, pt.x, pt.y); | ||
| 1751 | if (ti->dwFlags & TOUCHEVENTF_UP) | ||
| 1752 | mp_input_remove_touch_point(w32->input_ctx, ti->dwID); | ||
| 1753 | } | ||
| 1754 | } | ||
| 1755 | CloseTouchInputHandle((HTOUCHINPUT)lParam); | ||
| 1756 | talloc_free(inputs); | ||
| 1757 | return 0; | ||
| 1758 | } | ||
| 1716 | } | 1759 | } |
| 1717 | 1760 | ||
| 1718 | if (message == w32->tbtn_created_msg) { | 1761 | if (message == w32->tbtn_created_msg) { |
| @@ -1996,6 +2039,8 @@ static MP_THREAD_VOID gui_thread(void *ptr) · 277 unmodified lines | |||
| 1996 | update_backdrop(w32); | 2039 | update_backdrop(w32); |
| 1997 | if (w32->opts->cursor_passthrough) | 2040 | if (w32->opts->cursor_passthrough) |
| 1998 | update_cursor_passthrough(w32); | 2041 | update_cursor_passthrough(w32); |
| 2042 | if (w32->opts->native_touch) | ||
| 2043 | update_native_touch(w32); | ||
| 1999 | 2044 | ||
| 2000 | if (SUCCEEDED(OleInitialize(NULL))) { | 2045 | if (SUCCEEDED(OleInitialize(NULL))) { |
| 2001 | ole_ok = true; | 2046 | ole_ok = true; |
| @@ -2199,6 +2244,8 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg) · 197 unmodified lines | |||
| 2199 | update_maximized_state(w32, false); | 2244 | update_maximized_state(w32, false); |
| 2200 | } else if (changed_option == &vo_opts->window_corners) { | 2245 | } else if (changed_option == &vo_opts->window_corners) { |
| 2201 | update_corners_pref(w32); | 2246 | update_corners_pref(w32); |
| 2247 | } else if (changed_option == &vo_opts->native_touch) { | ||
| 2248 | update_native_touch(w32); | ||
| 2202 | } else if (changed_option == &vo_opts->geometry || changed_option == &vo_opts->autofit || | 2249 | } else if (changed_option == &vo_opts->geometry || changed_option == &vo_opts->autofit || |
| 2203 | changed_option == &vo_opts->autofit_smaller || changed_option == &vo_opts->autofit_larger) | 2250 | changed_option == &vo_opts->autofit_smaller || changed_option == &vo_opts->autofit_larger) |
| 2204 | { | 2251 | { |