diff --git a/gdk/win32/gdkdevicemanager-win32.c b/gdk/win32/gdkdevicemanager-win32.c index f4c258b3c8..19da420976 100644 --- a/gdk/win32/gdkdevicemanager-win32.c +++ b/gdk/win32/gdkdevicemanager-win32.c @@ -498,17 +498,30 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager) UINT32 i = 0; GList *current = NULL; - do + if (!getPointerDevices (&infos_count, NULL)) { - infos = g_new0 (POINTER_DEVICE_INFO, infos_count); - if (!getPointerDevices (&infos_count, infos)) - { - WIN32_API_FAILED ("GetPointerDevices"); - g_free (infos); - return; - } + WIN32_API_FAILED ("GetPointerDevices"); + return; + } + + infos = g_new0 (POINTER_DEVICE_INFO, infos_count); + + /* Note: the device count may increase between the two + * calls. In such case, the second call will fail with + * ERROR_INSUFFICIENT_BUFFER. + * However we'll also get a new WM_POINTERDEVICECHANGE + * notification, which will start the enumeration again. + * So do not treat ERROR_INSUFFICIENT_BUFFER as an + * error, rather return and do the necessary work later + */ + + if (!getPointerDevices (&infos_count, infos)) + { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + WIN32_API_FAILED ("GetPointerDevices"); + g_free (infos); + return; } - while (infos_count > 0 && !infos); /* remove any gdk device not present anymore or update info */ current = device_manager->winpointer_devices; @@ -520,9 +533,11 @@ winpointer_enumerate_devices (GdkDeviceManagerWin32 *device_manager) if (!winpointer_match_device_in_system_list (device, infos, infos_count)) { GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (device)); + GdkDeviceTool *tool = (GDK_DEVICE (device))->last_tool; gdk_device_update_tool (GDK_DEVICE (device), NULL); - gdk_seat_default_remove_tool (GDK_SEAT_DEFAULT (seat), (GDK_DEVICE (device))->last_tool); + gdk_seat_default_remove_tool (GDK_SEAT_DEFAULT (seat), tool); + g_clear_pointer (&tool, g_object_unref); gdk_seat_default_remove_slave (GDK_SEAT_DEFAULT (seat), GDK_DEVICE (device)); device_manager->winpointer_devices = g_list_delete_link (device_manager->winpointer_devices, diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 514608f13b..a53ab90485 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -2879,10 +2879,14 @@ gdk_event_translate (MSG *msg, break; } + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (IS_POINTER_PRIMARY_WPARAM (msg->wParam)) { - current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); - current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); + pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + current_root_x = pen_touch_cursor_position.x / impl->window_scale; + current_root_y = pen_touch_cursor_position.y / impl->window_scale; pen_touch_input = TRUE; last_digitizer_time = msg->time; } @@ -2909,10 +2913,14 @@ gdk_event_translate (MSG *msg, break; } + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (IS_POINTER_PRIMARY_WPARAM (msg->wParam)) { - current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); - current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); + pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + current_root_x = pen_touch_cursor_position.x / impl->window_scale; + current_root_y = pen_touch_cursor_position.y / impl->window_scale; pen_touch_input = TRUE; last_digitizer_time = msg->time; } @@ -2924,7 +2932,6 @@ gdk_event_translate (MSG *msg, gdk_winpointer_input_events (display, window, NULL, msg); - impl = GDK_WINDOW_IMPL_WIN32 (window->impl); if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE) { gdk_win32_window_end_move_resize_drag (window); @@ -2942,10 +2949,14 @@ gdk_event_translate (MSG *msg, break; } + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (IS_POINTER_PRIMARY_WPARAM (msg->wParam)) { - current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); - current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); + pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + current_root_x = pen_touch_cursor_position.x / impl->window_scale; + current_root_y = pen_touch_cursor_position.y / impl->window_scale; pen_touch_input = TRUE; last_digitizer_time = msg->time; } @@ -2958,8 +2969,6 @@ gdk_event_translate (MSG *msg, if (IS_POINTER_PRIMARY_WPARAM (msg->wParam) && mouse_window != window) crossing_cb = make_crossing_event; - impl = GDK_WINDOW_IMPL_WIN32 (window->impl); - if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE) { gdk_win32_window_do_move_resize_drag (window, current_root_x, current_root_y); @@ -2981,10 +2990,14 @@ gdk_event_translate (MSG *msg, break; } + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (IS_POINTER_PRIMARY_WPARAM (msg->wParam)) { - current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); - current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); + pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + current_root_x = pen_touch_cursor_position.x / impl->window_scale; + current_root_y = pen_touch_cursor_position.y / impl->window_scale; pen_touch_input = TRUE; last_digitizer_time = msg->time; } @@ -3017,10 +3030,14 @@ gdk_event_translate (MSG *msg, break; } + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (IS_POINTER_PRIMARY_WPARAM (msg->wParam)) { - current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); - current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); + pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + current_root_x = pen_touch_cursor_position.x / impl->window_scale; + current_root_y = pen_touch_cursor_position.y / impl->window_scale; pen_touch_input = TRUE; last_digitizer_time = msg->time; } @@ -3047,10 +3064,14 @@ gdk_event_translate (MSG *msg, break; } + impl = GDK_WINDOW_IMPL_WIN32 (window->impl); + if (IS_POINTER_PRIMARY_WPARAM (msg->wParam)) { - current_root_x = pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); - current_root_y = pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + pen_touch_cursor_position.x = GET_X_LPARAM (msg->lParam); + pen_touch_cursor_position.y = GET_Y_LPARAM (msg->lParam); + current_root_x = pen_touch_cursor_position.x / impl->window_scale; + current_root_y = pen_touch_cursor_position.y / impl->window_scale; pen_touch_input = TRUE; last_digitizer_time = msg->time; }