raylib icon indicating copy to clipboard operation
raylib copied to clipboard

[core] Mouse wheel not working in `PLATFORM_RPI` or `PLATFORM_DRM`

Open Trithilon opened this issue 1 year ago • 12 comments

Please, before submitting a new issue verify and check:

  • [Y] I tested it on latest raylib version from master branch
  • [Y] I checked there is no similar issue already reported
  • [Y] My code has no errors or misuse of raylib

Issue description

Any example which uses mouse-wheel input doesn't work (for instance - core_input_mouse_wheel). So any example which involves zoom-in using mouse-wheel won't work.

Environment

Running on RPI02W on Raspbian Lite Buster (32 bit).

Code Example

Just run make PLATFORM_RPI or DRM against raylib 4.2 src and examples on a Raspbian Buster Lite or Bullseye Lite installation. You will notice that in /core_input_mouse examples, you will be able to move the mouse, detect left, right and middle click - however you won't be able to detect mouse wheel movement in the core_input_mouse_wheel example.

Trithilon avatar Aug 22 '22 21:08 Trithilon

@Trithilon Afaik, native mouse device access does not support mouse wheel events, it requires a windowing system. I could be wrong, please correct me if you know any native headless mouse driver supporting mouse wheel.

raysan5 avatar Aug 22 '22 22:08 raysan5

The native /dev/mouse does support wheels, and for more complex mice, /dev/input/eventX nodes can be used too (no X/windowing system required to use evdev input).

ExplorerPS/2 (IntelliMouse Explorer) protocols, depending on what the
program reading the data wishes. ... You'll need ImPS/2 if you want to make use of a wheel on a USB
mouse```

clbr avatar Aug 23 '22 05:08 clbr

The native /dev/mouse does support wheels, and for more complex mice, /dev/input/eventX nodes can be used too (no X/windowing system required to use evdev input).

ExplorerPS/2 (IntelliMouse Explorer) protocols, depending on what the
program reading the data wishes. ... You'll need ImPS/2 if you want to make use of a wheel on a USB
mouse```

So something like this? https://forums.raspberrypi.com/viewtopic.php?t=30762#p267522

Trithilon avatar Oct 04 '22 18:10 Trithilon

Yes.

clbr avatar Oct 05 '22 05:10 clbr

Reviewed this issue but it seems mouse wheel is actually read: https://github.com/raysan5/raylib/blob/master/src/rcore.c#L6469

Please, could someone review this issue?

raysan5 avatar Oct 27 '22 11:10 raysan5

I was able to reproduce the issue on a Raspberry PI 2 Model B running bullseye in native mode.

Repro steps:

  • Cloned latest raylib from master
  • Compiled raylib and examples using PLATFORM_DRM
  • Ran core_input_mouse example
    • Mouse movement and button presses work as expected
  • Ran core_input_mouse_wheel
    • Mouse wheel input not working as expected

I verified that the system is registering mouse wheel input by running cat /dev/input/event1 and scrolling the mouse wheel.

raylib output from running core_input_mouse_wheel:

INFO: Initializing raylib 4.5-dev
INFO: Supported raylib modules:
INFO:     > rcore:..... loaded (mandatory)
INFO:     > rlgl:...... loaded (mandatory)
INFO:     > rshapes:... loaded (optional)
INFO:     > rtextures:. loaded (optional)
INFO:     > rtext:..... loaded (optional)
INFO:     > rmodels:... loaded (optional)
INFO:     > raudio:.... loaded (optional)
INFO: DISPLAY: No graphic card set, trying platform-gpu-card
INFO: DISPLAY: Failed to open platform-gpu-card, trying card1
INFO: DISPLAY: Failed to open graphic card1, trying card0
INFO: DISPLAY: Selected DRM connector mode 800x600 (800x600p@60)
INFO: DISPLAY: Upscaling required: Screen size (800x450) smaller than display size (800x600)
INFO: DISPLAY: Device initialized successfully
INFO:     > Display size: 800 x 600
INFO:     > Screen size:  800 x 450
INFO:     > Render size:  800 x 450
INFO:     > Viewport offsets: 0, 150
INFO: GL: Supported extensions count: 52
INFO: GL: OpenGL device information:
INFO:     > Vendor:   Broadcom
INFO:     > Renderer: VC4 V3D 2.1
INFO:     > Version:  OpenGL ES 2.0 Mesa 20.3.5
INFO:     > GLSL:     OpenGL ES GLSL ES 1.0.16
INFO: GL: VAO extension detected, VAO functions loaded successfully
INFO: GL: NPOT textures extension detected, full NPOT textures supported
INFO: GL: ETC1 compressed textures supported
INFO: TEXTURE: [ID 1] Texture loaded successfully (1x1 | R8G8B8A8 | 1 mipmaps)
INFO: TEXTURE: [ID 1] Default texture loaded successfully
INFO: SHADER: [ID 1] Vertex shader compiled successfully
INFO: SHADER: [ID 2] Fragment shader compiled successfully
INFO: SHADER: [ID 3] Program shader loaded successfully
INFO: SHADER: [ID 3] Default shader loaded successfully
INFO: RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)
INFO: RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)
INFO: RLGL: Default OpenGL state initialized successfully
INFO: TEXTURE: [ID 2] Texture loaded successfully (128x128 | GRAY_ALPHA | 1 mipmaps)
INFO: FONT: Default font loaded successfully (224 glyphs)
INFO: RPI: Opening keyboard device: /dev/input/event2
INFO: RPI: Opening input device: /dev/input/event1 (mouse )
WARNING: RPI: Failed to open Gamepad device, no gamepad available
INFO: TIMER: Target time per frame: 16.667 milliseconds
INFO: TEXTURE: [ID 2] Unloaded texture data from VRAM (GPU)
INFO: SHADER: [ID 3] Default shader unloaded successfully
INFO: TEXTURE: [ID 1] Default texture unloaded successfully
INFO: Window closed successfully

chrislavoy avatar Oct 27 '22 16:10 chrislavoy

Dug into this issue a bit and what I found was that CORE.Input.Mouse.currentWheelMove.y is getting set properly when the mouse wheel is scrolled. However, by the time GetMouseWheelMove() is called the value of currentWheelMove.y is 0. Changing GetMouseWheelMove() to use previousWheelMove.y instead of currentWheelMove.y results in the expected behavior.

As for why this is happening my best guess right now is GetMouseWheelMove() is never getting called before currentWheelMove.y is reset to 0 on https://github.com/raysan5/raylib/blob/master/src/rcore.c#L4872

Here is a sample of the output of some trace logs I added

WARNING: GetMouseWheelMove called
WARNING: BeginDrawing frame 82
WARNING: Updating previous mouse state
WARNING: EndDrawing frame 82

WARNING: GetMouseWheelMove called
WARNING: BeginDrawing frame 83
WARNING: Wheel updated
WARNING: Updating previous mouse state
WARNING: EndDrawing frame 83

WARNING: GetMouseWheelMove called
WARNING: BeginDrawing frame 84
WARNING: Wheel updated
WARNING: Updating previous mouse state
WARNING: EndDrawing frame 84

chrislavoy avatar Oct 27 '22 22:10 chrislavoy

Pretty sure there's a race condition. On PLATFORM_RPI and PLATFORM_DRM the currentWheelMove.y is updated in EventThread but gets zeroed out in PollInputEvents. I am experimenting with moving the logic of zeroing out currentWheelMove into EventThread so that it doesn't get clobbered by the main loop.

michaelfiber avatar Jan 22 '23 18:01 michaelfiber

I am testing this out as the fastest straight line to working Y scroll wheel functionality and it is working. I have to go through the code better when there's time to see what other side effects the mutex lock has.

https://github.com/michaelfiber/raylib/pull/1/files

michaelfiber avatar Jan 22 '23 21:01 michaelfiber

@michaelfiber thank you very much for looking into this issue! :)

raysan5 avatar Jan 23 '23 11:01 raysan5

I wanted to check some assumptions. I tested a few approaches and realized that at least in my testing the threads were unnecessary as was checking /dev/input/mouse_ files. I have been testing this on rpi3b+ and so far it works nicely:

https://github.com/michaelfiber/raylib/blob/mousescroll-rpi/examples/core/core_input_mouse.c

Is there some aspect I am missing that causes this to require threads? The event files are accessed with O_NONBLOCK and I can't find a noticeable performance hit from simply accessing it from the main loop.

And /dev/input/mouse_ appears to be a legacy compatibility hack. Each mouse file represents an event file. The threads in raylib spawned for mouse files never do anything because they won't return struct input_event

michaelfiber avatar Jan 30 '23 00:01 michaelfiber

And /dev/input/mouse_ appears to be a legacy compatibility hack.

I think so, it was originally implemented +8 years ago but many things have changed in this time... they can probably be removed/redesigned at this moment.

raysan5 avatar Jan 30 '23 16:01 raysan5

@michaelfiber Any progress on this issue?

Afair, I used threads because mouse input was not updated fast enough when running headless but as I said, it was implemented long time ago, I was very unexperienced about it and I probably missed some details.

If you tested another approach and it worked ok, feel free to send a PR. If it is simpler and works better, that's a win! If not, somebody will complain sooner or later! :P

raysan5 avatar May 21 '23 09:05 raysan5

I have been testing something out that is looking pretty good but I haven't yet tackled integrating it with rcore. That is a big chunk of stuff to integrate with. The change I was testing impacts all keyboard, gamepad and mouse input for PLATFORM_DRM/RPI.

I should have some time in the next couple of weeks to circle back to this and try to get something working pushed.

michaelfiber avatar May 21 '23 15:05 michaelfiber

@michaelfiber Sure! Take your time! Afaik, you are one of the users that has worked more extensively with raylib RPI to date!

raysan5 avatar May 21 '23 15:05 raysan5