-
Notifications
You must be signed in to change notification settings - Fork 1
Description
UInput Orchestrator (UIO)
What is the idea?
A daemon that manages connections between mappers by creating, assigning and re-assigning multiple uinput devices, but could be extended to something else later. This should result in a stable path where multiple input mappers can process an input device in a deterministic order.
Mappers connect through a few functions in a library and can request file descriptors to matching (virtual) input devices. UIO's job is to ensure that
Disclaimer: this is an early draft and I have not done enough research to be sure that it is technically feasible (or even possible).
Let's start with a few diagrams.
Each Mapper has contexts, identified by it's path (abbreviated here to M#) and role. Roles can be requested by the mapper or configured by the user. If configured by the user, the mapper can request available roles from UIO.
If a mapper wants to create a context, a GUI asks the user to confirm. "New" is where new contexts pop up by default.
All contexts are specific to an input device (although input devices could be grouped for easier configuration).
Startup and first events
I hope this is somewhat clear..
UIO makes sure there is a chain of (for now!) uinput devices. It can open and create input devices, then shares the FDs with mappers through UIOInput/UIOOutput. Virtual devices can be kept open as it deems necessary (e.g. for short lived scripts / a short while after a mapper exits, in case it's just restarting..).
I hope it is possible to manage access rights to the virtual devices in a safe and stable way.
UIOInput and UIOOutput offer transparent read/write functions. My plan is to use uinput for now, but this may be extended and configured to support other ways of communication between mappers like a direct shared buffer (for performance) or one that is managed by UIO and keeps state of all keys (lower performance, but safer handling of some cases).
read_evdev()
means that it returns the event as evdev would. We could add transformations to libinput structs, etc. later.
Window change
We may have options to handle cases where a keycode changes while it's pressed. But I'm not sure how/where to do that yet.
Advantages
- We can start implementing right now. (ok.. after sorting out a few things)
- Extensible
- Does not require big changes to existing mappers (I hope).
Disadvantages (for now)
- May create a lot of virtual input devices.
- Is this bad for performance?
- Does not solve all problems (but maybe can be extended to)
Some open questions
-
Implementation details
- how to handle crashing mappers?
- can they kill UIO?
- FDs can be shared between applications. But what are the limitations?
- is a grab transferred? If so, how? Do both applications have it?
- what happens if it's closed by one application?
- What if 2 write to it at the same time?
- how to make it stable & secure?
- what is the best way to handle mappers entering or leaving the chain?
- how to handle crashing mappers?
-
UIOOutputRequirements - a struct holding the parameters by which a fitting output is chosen.
- should contain:
- Type of the device (mouse, keyboard, tablet, joystick, etc.)
- Necessary output capabilities
- What else?
- should contain: