Open tomlankhorst opened 5 years ago
No, there isn't. I've heard this request a couple of times over the years though, so I'll keep it in mind for the upcoming protocol re-design that I wanted to do for some time now. Leaving this open as a feature request.
Okay, I might submit a (quick) PR these days to realize this for the current protocol.
I'm wondering if, instead of changing the protocol, spacenavd
could just open a new socket per additional device, using the same protocol per socket. libspnav
already has functionality to configure the socket path to use.
It's not ideal from the perspective of hotplugging, but it might be a quicker fix.
That might indeed be a quick and easy way to support multiple devices. It would need some refactoring of how devices are handled internally, but would require no protocol changes. And libspnav could hide most of the details from user apps, making it possibly as simple as setting a global flag about multi-device input before opening the connection, and handling events slightly differently to take device id into account...
Digging in a bit more, it looks like the functionality in https://github.com/FreeSpacenav/spacenavd/commit/7145788c5e1c0c381aec791e157dab6b6a4144ab lays a lot of the groundwork for using the existing single-socket approach. If the request protocol (from client to spacenavd
) is expanded so that set_client_device
can be called, then each client can listen to a specific device. That approach requires some protocol changes, but they should be backwards compatible, requiring an addition to
enum {
/* per-client settings */
REQ_SET_NAME = REQ_BASE,/* set client name: Q[0-5] next 24 bytes Q[6] remaining length - R[6] status */
REQ_SET_SENS, /* set client sensitivity: Q[0] float - R[6] status */
REQ_GET_SENS, /* get client sensitivity: R[0] float R[6] status */
REQ_SET_EVMASK, /* set event mask: Q[0] mask - R[6] status */
REQ_GET_EVMASK, /* get event mask: R[0] mask R[6] status */
If we're adding things to the protocol, I think binding a device to each client (and having the client open multiple connections) feels ackward.
I think I'd rather co-opt, on request by the application to enable multi-device mode, the extremely useless last field of motion events, for sending a device id. So far it was used to transmit a period between events, which nobody ever uses for anything, and I added initially just because the 3dconnexion X11 protocol had it.
The "activate multi-device mode" request can return the number of devices, or a new request can be added for that, as well as a new event type for when devices come and go.
I think all device requests have empty fields which can be used to specify which device the request applies to, so that applications can properly enumerate all devices. And although I'm pretty sure currently all unused fields are set to 0, it's probably prudent to explicitly ignore it if the client has not activated multi-device mode.
In reality since the new protocol was introduced, the biggest difficulty I think is in how to handle multiple devices within the daemon at this point. Beyond the refactoring, there's also the issue of what to do with configuration. Things like device sensitivity, axis and button mappings and so on, are really device-specific, but currently there's just a single global configuration, and changing that would necessarilly complicate the configuration syntax. But I guess one step at a time...
If we're adding things to the protocol, I think binding a device to each client (and having the client open multiple connections) feels ackward.
but it seems like this was the intent of
is there an alternative intent that I'm missing?
No, you're right, that was the intention behind this mechanism, and I guess it's also useful to be able to select a specific device and receive only events from that. But:
client->dev
is always null at this point, defaulting to the first device.as well as a new event type for when devices come and go.
I think this is already in place with event_dev
/ spnav_event_dev
Nice! I forgot I had done that. Unfortunately I also forgot to add the various device operations (like DEV_ADD) in the protocol header. So that part is covered, and the omissions are easily mended.
I'd like to know how the adaptation for multiple mice is progressing, I really need this feature now!
Is there in the current implementation a way to distinguish input from two or more devices? On first sight, there seems to be no facility in the event structures of
libspnav
nor in the raw data from the UNIX sockets that differentiates an event produced by device A or B.Is there a way to achieve this differentiation?