Skip to content

Commit 7cff339

Browse files
committed
SDL2: warn at init when winraw input driver is selected
The Windows winraw input driver does not work alongside the SDL2 video driver because SDL2 internally registers for raw input and drains the WM_INPUT stream via GetRawInputBuffer() to feed its own keyboard / mouse APIs. winraw's hidden HWND_MESSAGE window then never sees any input events, so keyboard / mouse polling silently stops working. This is a fundamental architectural mismatch and not something the SDL2 video driver can fix from RA's side - SDL owns its window's WndProc. Unlike the d3d8 / d3d9 / d3d11 / d3d12 drivers, which create their main window themselves with a winraw-aware WndProc (wnd_proc_d3d_winraw, gfx/common/win32_common.c) that forwards the relevant focus / input messages, SDL_CreateWindow installs SDL's own WndProc and we have no clean way to subclass or replace it. The bug has existed since both drivers existed, but went largely unnoticed before the recent SDL2 backend work because the SDL2 driver was missing menu rendering and rarely used as a primary choice. Now that it is feature-complete, more users will hit the combination. Detect the broken combo at sdl2_gfx_init time and emit two RARCH_WARN lines with concrete actionable guidance ("switch to dinput in Settings -> Drivers -> Input") so the user has a clear explanation instead of a black-hole input experience. Does not refuse to init - gamepad-only users still get a working setup. Gated on _WIN32 (and not _XBOX / __WINRT__) since winraw is Windows-only. See input/drivers/winraw_input.c for the input side.
1 parent f2bb729 commit 7cff339

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

gfx/drivers/sdl2_gfx.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <retro_inline.h>
2323
#include <gfx/scaler/scaler.h>
2424
#include <formats/image.h>
25+
#include <string/stdstring.h>
2526

2627
#ifdef HAVE_CONFIG_H
2728
#include "../../config.h"
@@ -342,6 +343,31 @@ static void *sdl2_gfx_init(const video_info_t *video,
342343
if (!vid)
343344
return NULL;
344345

346+
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
347+
/* SDL2 internally uses RegisterRawInputDevices and drains the raw
348+
* input buffer via GetRawInputBuffer() to feed its own keyboard /
349+
* mouse APIs. This consumes the WM_INPUT stream that the winraw
350+
* input driver's hidden HWND_MESSAGE window depends on, so its
351+
* keyboard / mouse polling stops receiving events.
352+
*
353+
* Unlike the d3d8 / d3d9 / d3d11 / d3d12 drivers - which create
354+
* their main window with a winraw-aware WndProc
355+
* (wnd_proc_d3d_winraw, see gfx/common/win32_common.c) - the SDL2
356+
* window's WndProc is owned by SDL and we cannot replace it.
357+
*
358+
* Warn loudly so users hitting silent broken-input understand
359+
* what to change instead of assuming the driver is broken. */
360+
if (string_is_equal(settings->arrays.input_driver, "raw"))
361+
{
362+
RARCH_WARN("[SDL2] The 'raw' (winraw) input driver is "
363+
"incompatible with the SDL2 video driver - SDL2 consumes "
364+
"Windows raw input internally.\n");
365+
RARCH_WARN("[SDL2] Mouse and keyboard input will not work. "
366+
"Switch the input driver to 'dinput' under "
367+
"Settings -> Drivers -> Input.\n");
368+
}
369+
#endif
370+
345371
RARCH_LOG("[SDL2] Available renderers (change with $SDL_RENDER_DRIVER):\n");
346372
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i)
347373
{

0 commit comments

Comments
 (0)