Closed Buttars closed 1 year ago
Yeah, xremap does create a virtual device. It lives under /dev/input
, and if you read the name of devices under that directory, you should find something named like xremap pid=1234
.
Hey @k0kubun, thanks for the response.
When I search with find /dev -name "**xremap**"
it returns nothing.
[~]$ xremap ~/.config/xremap/xremap.config
Selecting devices from the following list:
------------------------------------------------------------------------------
/dev/input/event0 : Sleep Button
/dev/input/event1 : Power Button
/dev/input/event10: RAZER Razer Mouse Dock
/dev/input/event11: RAZER Razer Mouse Dock
/dev/input/event14: Razer Razer DeathAdder V2 Pro
/dev/input/event15: Razer Razer DeathAdder V2 Pro Keyboard
/dev/input/event16: Razer Razer DeathAdder V2 Pro
/dev/input/event17: Razer Razer DeathAdder V2 Pro
/dev/input/event18: Razer Razer DeathAdder V2 Pro Consumer Control
/dev/input/event19: Asus WMI hotkeys
/dev/input/event2 : Power Button
/dev/input/event20: HDA ATI HDMI HDMI/DP,pcm=3
/dev/input/event21: HDA ATI HDMI HDMI/DP,pcm=7
/dev/input/event22: HDA ATI HDMI HDMI/DP,pcm=8
/dev/input/event23: HDA ATI HDMI HDMI/DP,pcm=9
/dev/input/event24: HDA ATI HDMI HDMI/DP,pcm=10
/dev/input/event25: HDA ATI HDMI HDMI/DP,pcm=11
/dev/input/event3 : SteelSeries SteelSeries Apex 7
/dev/input/event4 : SteelSeries SteelSeries Apex 7
/dev/input/event5 : SteelSeries SteelSeries Apex 7 Consumer Control
/dev/input/event7 : SteelSeries SteelSeries Apex 7 Mouse
/dev/input/event8 : RAZER Razer Mouse Dock
/dev/input/event9 : RAZER Razer Mouse Dock Keyboard
------------------------------------------------------------------------------
Selected keyboards automatically since --device options weren't specified:
------------------------------------------------------------------------------
/dev/input/event11: RAZER Razer Mouse Dock
/dev/input/event15: Razer Razer DeathAdder V2 Pro Keyboard
/dev/input/event17: Razer Razer DeathAdder V2 Pro
/dev/input/event3 : SteelSeries SteelSeries Apex 7
/dev/input/event4 : SteelSeries SteelSeries Apex 7
/dev/input/event9 : RAZER Razer Mouse Dock Keyboard
------------------------------------------------------------------------------
tree /dev/input
[~]$ tree /dev/input
/dev/input
├── by-id
│ ├── usb-Razer_Razer_DeathAdder_V2_Pro_000000000000-event-if01 -> ../event16
│ ├── usb-Razer_Razer_DeathAdder_V2_Pro_000000000000-event-if03 -> ../event18
│ ├── usb-Razer_Razer_DeathAdder_V2_Pro_000000000000-event-mouse -> ../event14
│ ├── usb-Razer_Razer_DeathAdder_V2_Pro_000000000000-if01-event-kbd -> ../event15
│ ├── usb-Razer_Razer_DeathAdder_V2_Pro_000000000000-if02-event-kbd -> ../event17
│ ├── usb-Razer_Razer_DeathAdder_V2_Pro_000000000000-mouse -> ../mouse2
│ ├── usb-RAZER_Razer_Mouse_Dock-event-if01 -> ../event10
│ ├── usb-RAZER_Razer_Mouse_Dock-event-mouse -> ../event8
│ ├── usb-RAZER_Razer_Mouse_Dock-if01-event-kbd -> ../event9
│ ├── usb-RAZER_Razer_Mouse_Dock-if02-event-kbd -> ../event11
│ ├── usb-RAZER_Razer_Mouse_Dock-mouse -> ../mouse1
│ ├── usb-SteelSeries_SteelSeries_Apex_7-event-if03 -> ../event5
│ ├── usb-SteelSeries_SteelSeries_Apex_7-event-kbd -> ../event3
│ ├── usb-SteelSeries_SteelSeries_Apex_7-if02-event-kbd -> ../event4
│ ├── usb-SteelSeries_SteelSeries_Apex_7-if03-event-mouse -> ../event7
│ └── usb-SteelSeries_SteelSeries_Apex_7-if03-mouse -> ../mouse0
├── by-path
│ ├── pci-0000:00:14.0-usb-0:7.1:1.0-event-mouse -> ../event14
│ ├── pci-0000:00:14.0-usb-0:7.1:1.0-mouse -> ../mouse2
│ ├── pci-0000:00:14.0-usb-0:7.1:1.1-event -> ../event16
│ ├── pci-0000:00:14.0-usb-0:7.1:1.1-event-kbd -> ../event15
│ ├── pci-0000:00:14.0-usb-0:7.1:1.2-event-kbd -> ../event17
│ ├── pci-0000:00:14.0-usb-0:7.1:1.3-event -> ../event18
│ ├── pci-0000:00:14.0-usb-0:7.2:1.0-event-mouse -> ../event8
│ ├── pci-0000:00:14.0-usb-0:7.2:1.0-mouse -> ../mouse1
│ ├── pci-0000:00:14.0-usb-0:7.2:1.1-event -> ../event10
│ ├── pci-0000:00:14.0-usb-0:7.2:1.1-event-kbd -> ../event9
│ ├── pci-0000:00:14.0-usb-0:7.2:1.2-event-kbd -> ../event11
│ ├── pci-0000:00:14.0-usb-0:8:1.0-event-kbd -> ../event3
│ ├── pci-0000:00:14.0-usb-0:8:1.2-event-kbd -> ../event4
│ ├── pci-0000:00:14.0-usb-0:8:1.3-event -> ../event5
│ ├── pci-0000:00:14.0-usb-0:8:1.3-event-mouse -> ../event7
│ ├── pci-0000:00:14.0-usb-0:8:1.3-mouse -> ../mouse0
│ ├── pci-0000:00:14.0-usbv2-0:7.1:1.0-event-mouse -> ../event14
│ ├── pci-0000:00:14.0-usbv2-0:7.1:1.0-mouse -> ../mouse2
│ ├── pci-0000:00:14.0-usbv2-0:7.1:1.1-event -> ../event16
│ ├── pci-0000:00:14.0-usbv2-0:7.1:1.1-event-kbd -> ../event15
│ ├── pci-0000:00:14.0-usbv2-0:7.1:1.2-event-kbd -> ../event17
│ ├── pci-0000:00:14.0-usbv2-0:7.1:1.3-event -> ../event18
│ ├── pci-0000:00:14.0-usbv2-0:7.2:1.0-event-mouse -> ../event8
│ ├── pci-0000:00:14.0-usbv2-0:7.2:1.0-mouse -> ../mouse1
│ ├── pci-0000:00:14.0-usbv2-0:7.2:1.1-event -> ../event10
│ ├── pci-0000:00:14.0-usbv2-0:7.2:1.1-event-kbd -> ../event9
│ ├── pci-0000:00:14.0-usbv2-0:7.2:1.2-event-kbd -> ../event11
│ ├── pci-0000:00:14.0-usbv2-0:8:1.0-event-kbd -> ../event3
│ ├── pci-0000:00:14.0-usbv2-0:8:1.2-event-kbd -> ../event4
│ ├── pci-0000:00:14.0-usbv2-0:8:1.3-event -> ../event5
│ ├── pci-0000:00:14.0-usbv2-0:8:1.3-event-mouse -> ../event7
│ ├── pci-0000:00:14.0-usbv2-0:8:1.3-mouse -> ../mouse0
│ └── platform-asus-nb-wmi-event -> ../event19
├── event0
├── event1
├── event10
├── event11
├── event14
├── event15
├── event16
├── event17
├── event18
├── event19
├── event2
├── event20
├── event21
├── event22
├── event23
├── event24
├── event25
├── event3
├── event4
├── event5
├── event6
├── event7
├── event8
├── event9
├── mice
├── mouse0
├── mouse1
├── mouse2
└── mouse3
Any idea where the virtual device is hiding?
Can you try running a couple of xremap processes at once? The second one could use --device xreamp
, and that one should list the xremap device. It's intentional that the first process doesn't list a device it's going to create.
That worked. /dev/input/event6 : xremap pid=18420
I'm assuming this wont be the same between reboots or even if xremap is killed and restarted? Is there any pattern I can use to help identify the correct input event?
I'm trying to pass this into a VM which requires an explicit reference. Not sure how to approach this problem. Is there a way to explicitly set the virtual output event/device name?
I'm not sure either.
As a workaround, you could modify this line to just pass "xremap"
, build xremap with that source, and run it. It should always give you xremap
as a device name.
I'm not sure either.
As a workaround, you could modify this line to just pass
"xremap"
, build xremap with that source, and run it. It should always give youxremap
as a device name.
Would it make sense for a feature to add named paths to each of the events under /dev/inputs/by-id
for each instance of xremap? Might make a good first issue and give me a reason to dive into rust.
@k0kubun Would you be open to having xremap create a symbolic link in /dev/input/by-id? Would you want this to be created for every virtual device or as a flag/config item? What would a reasonable syntax be? xremap-virtual-device-X
?
Oh sorry, I somehow missed the notification for the previous reply.
/dev/inputs/by-id for each instance of xremap? What would a reasonable syntax be? xremap-virtual-device-X?
I'm tempted to call it xremap0
, xremap1
, ... if that's allowed.
Would you mind creating a PoC pull request? I'd be open to merging it as long as it's possible with or without sudo on the supported platforms. As of now, I'm not sure if I can implement it myself.
I'm working on one now. Rust is very new to me so it's going to take some time as I learn the weird language. I'll open a PR as soon as possible. Thanks for the replies.
@k0kubun I've got a POC working but it requires the user to change the owner of the /dev/input/by-id directory which is probably (certainly) a bad idea. Typically these symlinks are created using a udev rule. Do you know of any way udev or another native linux library can be used to create the symlink programmatically in rust?
No, I don't know of any. I have a couple of questions:
/dev/input
? Can you specify non-/dev/input
path in virt-manager?/dev/input
and optionally create the symlink only if possible?Do you really need to have it under /dev/input? Can you specify non-/dev/input path in virt-manager?
Yes that is an option, although /dev/input/by-id is the linux appropriate place to put those type of device symlinks.
The trouble is that virt-manager does not offer a scripting feature without breaking down into qemu so the reference would have to be semi-static. Like xremap0, xremap1,...xremapN worked for me because I know I only run one instance and I control the instances of xremap. This would be less useful if the linux box was a long lived multi-user session but that's probably outside the scope of the desired change.
Could you check the permission of /dev/input and optionally create the symlink only if possible?
Changing the ownership of that directory is very likely a bad idea. Linux relies on that directory for all sorts of input related stuff and I'm not sure what the behavior would be. Ownership resets on each boot since it's the kernel that creates that directory and assigns ownership to root directly. It's possible to prevent this with a udev rule but that's a rabbit hole I don't want to go down and breaks the simplicity of using xremap.
I'm seriously considering opening an issue with the linux kernel to extend the uinput UI_DEV_SETUP macro to allow the definition of a device by-id name and have it create a symlink in kernel. What is weird is physical devices get this functionality but they don't extend that to virtual devices created with uinput.
...
Udev rules can target specific vendor and device ids. If something more unique was used than the current 1234
and 5678
then udev could run a script on each of those devices. That script would run as root since it's invoked by udev and would have the necessary permissions to create the symlinks.
The vendor and product id could be something like 1337
and 1111
as long as the vendor ID is unique that would work for udev. I could then write a local bash script to add the xremapX
symlinks to /dev/input/by-id. This isn't a xremap centric approach but would do what I need it to.
I'd appreciate your feedback on the proposed approach.
I'd appreciate your feedback on the proposed approach.
I'm not sure if I follow what you're trying to do since I'm not familiar with udev/product id/vendor id. Could you make a change that is needed on the xremap side as a pull request? As long as the change on the xremap side is simple enough, I'd accept the patch to make your solution viable.
Off topic but related, devices have a Uniq
field that contains a unique identifier like a serial number but yet again uinput doesn't support that field...If it did it would be trivial to use that value in udev to create a symlink.
Here is a rough draft. If the user proves the --unique-id
flag the device is named xremap uniq=XXXXX
. uniq
was chosen to mimic the unique value that should go onto the Uniq field of the device if uinput supported it. I'm hoping in the future the kernel will support that field. The refactor would be simple to migrate that argument onto the device property and remove the conditional name logic from the device.rs
I accidentally closed https://github.com/k0kubun/xremap/pull/346 and couldn't reopen it, so I opened another one with your change at https://github.com/k0kubun/xremap/pull/347. Now I understand what you're trying to do, so I appreciate your work.
I have one suggestion. Assuming there's no use case for running multiple xremap processes besides testing, can we just name the first device xremap
and add the pid={}
suffix only to devices added later? This would still give you a reliable device name while not adding a new command-line option. WDYT?
What about multi-user sessions? That's not my use case but considering it might be others. How does xremapper handle multi-user sessions? I assume that since it runs in user space the remapping would only apply to the current signed in user. Am I wrong thinking that? Or since xremapper is somehow hooking the physical device and creating a virtual one does it carry across sessions?
It would make sense to have the ability to create named virtual devices for complex setups especially ones where multiple virtual devices are necessary.
Another use case where having named devices may be useful is combining multiple axis devices like controllers or joysticks into a single virtual device allowing the mapping of the signals to specific binds but that may be out of scope.
I'm imagining a use case where a user wants two separate virtual inputs to group several devices together. Multiple many-to-one virtual devices.
Do you know how Linux handles when a user plugs in two of the same model of keyboard?
We could name it xremap user=$USER
, but I think using xremap
by default and falling back to xremap pid=$pid
should be also fine unless somebody really needs it.
Changing device names is okay with me, but I'm reluctant to add a command line flag when your problem could be solved without it. As long as "that's not your use case" and I don't know of anybody else who needs it, at least I don't want to add a command like flag for somebody that does not exist.
If you want to object to the default xremap
& xremap pid=$pid
fallback idea, you should bring your own use case. Please don't "imagine a use case" or talk about something "that's not your use case". We can easily adjust device names when somebody says they need it. But once you add a command-line flag, that's harder to change. So I'm very reluctant to merge that portion unless we know there's a real person who will use it.
Do you know how Linux handles when a user plugs in two of the same model of keyboard?
No, I don't. Feel free to investigate that, but I'd rather not comply with that since leaving it pid=$pid
is rather more backward compatible for secondary processes than changing it.
Filed https://github.com/k0kubun/xremap/pull/348. Can you test that branch? If that satisfies your use case, I don't want to add a command-line flag or change device names any further.
Yes that satisfies my use case, for now.
No, I don't. Feel free to investigate that, but I'd rather not comply with that since leaving it
pid=$pid
is rather more backward compatible for secondary processes than changing it.
I agree, I think working with the linux kernel to expand the uinput api to support the uniq
device attribute is a more reasonable approach. I'll open up an issue to see what the kernel maintainers think.
I think you're correct that it's probably a bad idea to try and make xremap handle unique naming when that responsibility should lie with udev.
OK, I'll merge and release that feature.
I have a GPU passthough setup using virt-manager. To pass through they keyboard via virtio I have to pass the keyboard event device. In my case
/dev/input/by-id/usb-SteelSeries_SteelSeries_Apex_7-event-kbd
.xremap intercepts my keyboard and makes it not output to this device, I'm assuming this is how the remapping works. This breaks my virtio and virt-manager setup because there is no way to map the keyboard to the virtio input device.
How can I bind to the events of xremap? Is there a virtual device I can bind to?