KarsMulder / evsieve

A utility for mapping events from Linux event devices.
GNU General Public License v2.0
220 stars 12 forks source link

Make virtual keyboard acts like "physical" #32

Open t0msk opened 1 year ago

t0msk commented 1 year ago

Hello,

I used to use evsieve for VM (used to ignore some keys so I could use them in host for some actions like mute mic, etc..), and it is great, but I was using ShadowPC (cloud streaming platform), and they supports USB device redirection, so I can pass whole keyboard to their VM, but problem is that I all keys are passed to VM, and my hotkeys on host machine doesn't work anymore, so I think evsieve could help me again :) ensieve creates virtual keyboard (guest-keyboard) which works as want, problem is that ShadowPC doesn't recognize it as my physical USB device, and I don't have option to pass it to the VM.

It is the biggest dealbreaker for me, because I want at least one button "blacklist" so it will not be passed to VM, so I could use that button on my keyboard for some hotkeys on my host machine like mute mic, etc...

example of my script:

#!/bin/bash

evsieve --input /dev/input/by-id/usb-Razer_Razer_BlackWidow_Chroma_V2-if01-event-kbd grab \
    --map key:scrolllock key:leftctrl key:rightctrl \
        --output key:grave \
        --output create-link=/dev/input/by-id/guest-keyboard &

Thank you very much

KarsMulder commented 1 year ago

I haven't actually been able to try out ShadowPC yet (current stumble block: ShadowPC's client "LOG IN WITH BROWSER" button refuses to work for me), but the documentation (this page)'s claim that it can forward "any USB device" suggests to me that is is intercepting the USB packets and relaying them over the internet.

(If I'm wrong and the actual issue is just that I'm using the wrong flags when creating uinput devices, please correct me.)

The way that the Linux kernel input system works is that various drivers in the Linux kernel or userspace interpret the messages that they receive from the USB devices and turn them into events according to the Linux-specific evdev protocol, which is an abstraction layer away from how the USB devices themselves communicate.

So I suppose that to do this, Evsieve would have to translate this evdev protocol back to the USB protocol, and then tell the kernel somehow to pretend that there is an extra USB device which emits those USB messages.

I think Qemu is currently doing the first part already. A cursory search that something called "FunctionFS" may be used to achieve the second part. I have not yet figured out how much effort it would take to actually implement this.

My current opinion is that while I wouldn't consider this to be completely out of scope for evsieve, it does give some vibes of serious scope creep (we were supposed to handle evdev events, now we're emulating the USB protocol?), which puts it pretty low on the priority lift.

t0msk commented 1 year ago

As okay, so this feature is not going to be happen any time soon right? :/

Anyways, do you know some solution what could help me with this issue? :/

KarsMulder commented 1 year ago

Sorry, I know no direct solutions.

I'm getting the impression that FunctionFS may be intended for something different than what I was trying to accomplish. There is less information available on the question of "how to make the host think that there is an additional USB device" than I'd expect. The closest thing to this purpose I've found so far is USB/IP.

EDITED: It seems to be possible to use evdev passthrough with Qemu to turn an event device on the host into a virtual USB device on the guest. With that in mind, a highly unwieldy way to get this done could be to use evsieve to filter and event device on the host, then using evdev passthrough with Qemu to create a virtual machine with access to that event device, a virtual network connection to the host, a Linux kernel, and as few other resources as possible, and then use USB/IP to relay the virtual USB devices back to the host.

That is sufficiently unwieldy that even I myself wouldn't bother with that though...

Thinking about some other approaches...

In case you do not want a certain key like key:grave to be sent to the virtual machine over ShadowPC, you could consider to just send that key using ShadowPC and your virtual machine to just ignore that key? I think that on Windows it is possible to disable keys using Regedit.

I wonder if it is possible to configure ShadowPC on the host to duplicate an USB device instead of taking it over completely? In that case, you could try the following approach:

Finally, though decidedly low-tech and inelegant, there is always the option of buying a cheap second keyboard, putting it at a as-nonintrusive-as-possible position on your desk, and using a few dedicated keys on that keyboard as hotkeys for your host computer.