diff --git a/gdk/win32/gdkdevicemanager-win32.c b/gdk/win32/gdkdevicemanager-win32.c index ecdb9916de..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;