Raw, HID and Direct libInput Protocol.
Submitted by x41..@..ux.com
Assigned to Wayland bug list
Description
I work in game development and I am looking to test some of my games on Wayland. I currently have the UE4Editor running on Fedora 22 GNOME Shell Wayland without X11.
This is related to the following issues: https://bugs.freedesktop.org/show_bug.cgi?id=84014 https://bugs.freedesktop.org/show_bug.cgi?id=85715
Firstly I suggest you read the UE4 source first (it is now free if you accept the EULA) to see how it is implementing mouse input.
IDEA:
- Raw motion:
I propose a new interface wl_input which will receive generic libInput events allowing the application to receive and then process these libinput events directly. It will only receive these events if the compositor allows; either because the window has focus or the device is a global device. These could also be sensor devices or any other HID device.
This will include a new libinput relative axis event which will support the need for a "relative pointer". There would be an option for opening the default device for a specific seat which would mostly be the same mouse as the wl_pointer (but should not always be assumed). This would allow axis events from an arbitrary list of devices to be mapped into a game input, allowing a user to bind a mouse to look and thumbstick to move, all from the same api. The game would always still receive the normal wl_pointer motion events if the wl_pointer would be inside the input area allowing it to draw on screen cursors in the correct place. This will then be extended to support joystick devices and 6dof, and hmds all as a generic libinput device. The axis events will transmit all information about dead-zones, sensitivity, normalization and DPI should any of this information change in-fight by WM settings.
- Locking/Confinement:
If the application opens the default device and it is the same device as the wl_pointer (as in moving the wl_input device will move the wl_cursor) then it is up to the compositor to alert the user etc. based on sandbox settings and then the confinement can happen. It is as if the application has become fullscreen, outside the window area the cursor will be hidden. If the user sets the default device to a different mouse or a gamepad axis then the game will not receive a lock/confinement as it does not need one.
Applications should not assume the pointer can ever become confined or locked by any direct action it takes itself or that a user wants to play a game using the default mouse. I may want any device to be picked as my default 2D relative movement device, including a second mouse I may have plugged in.
REASONING:
The main sticking point is the idea of a "relative pointer".
Firstly a "relative pointer" does not exist. Pointer != mouse != cursor.
A mouse is a relative device, the information retrieved is an axis delta and not an absolute position. It may or may not have acceleration applied at various levels. When used for input in a game this is just another axis. It is not a pointer.
A pointer is an absolute device with an input area. What the device is pointing at in the input area is a fixed absolute position with no acceleration. You cannot lock, grab or restrict pointers because there is no feedback to the device to prevent its movement.
What we are currently doing is mapping a mouse into a pointer with an infinite input area and calling this point the "cursor". You can move or hide and lock the cursor because the mouse is a relative device. But when the cursor is also used for a pointer type device you can no-longer do this.
I think it is a mistake to base off the current idea SDL has of a "relative mouse mode" because this is an abstraction of many different operating systems and does not map directly to the wayland idea of a pointer.
If an application is intending to receive relative motion events it should be using a completely separate interface than the wl_pointer as it could be a completely different device such as an onboard accelerometer. The wl_pointer co-ordinates should still be wherever the point is pointing at.
Most games currently use Windows and Windows mostly use Raw HID input events received via a WM_INPUT event to handle the "high precision", "raw" mouse. They do not use anything related to "relative" mouse at all. UE4 for example still expects that the mouse will be visible and move around as normal when in this mode and requests the lock/capture separately. This api is fairly analogous to libinput and can support any HID device.
Secondly some devices such as gamepads, joysticks, HMDs, 6DOF input device, mice may also be used by many applications and need to be associated with a certain seat and window/surface focus. When swapping between games for example, the gamepad should only input in the current focus. Adding in all these different cases into the wayland protocol is not viable.
I will try to work out a small bit of code and submit it but I am already working on too many projects and I may not have time.