Giter Club home page Giter Club logo

evdev-proxy's Introduction

Evdev Proxy

Proxy multiple evdev input devices to single virtual uinput device.

Primary usecase are - passthrough input events to qemu-evdev device with support of input device hotplug/unplug. For example using some kvm-switches will detach physical evdev devices from qemu on first switch to another machine and only way to attach it back is to restart the guest.

Note:

This is early version, WIP.

Installation

Configuration

Configuration is pretty straightforward, please refer to example config.toml.

How to use with QEmu

Assuming you use example devices from config.toml, just add following args to your qemu command line:

-device virtio-keyboard-pci,id=input2,bus=pci.10,addr=0x0 \
-device virtio-mouse-pci,id=input3,bus=pci.11,addr=0x0 \
-object input-linux,id=aio,evdev=/dev/input/by-id/virtual-event-EvdevProxyAIO,grab_all=on,repeat=on

Or this if you want to use separate keyboard and mouse devices:

-device virtio-keyboard-pci,id=input2,bus=pci.10,addr=0x0 \
-device virtio-mouse-pci,id=input3,bus=pci.11,addr=0x0 \
-object input-linux,id=kbd,evdev=/dev/input/by-id/virtual-event-EvdevProxyKeyboard,grab_all=on,repeat=on \
-object input-linux,id=mouse,evdev=/dev/input/by-id/virtual-event-EvdevProxyMouse

If you use libvirt you can do the same with following domain XML:

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  ...
  <input type="keyboard" bus="virtio">
    <address type="pci" domain="0x0000" bus="0x0a" slot="0x00" function="0x0"/>
  </input>
  <input type="mouse" bus="virtio">
    <address type="pci" domain="0x0000" bus="0x0b" slot="0x00" function="0x0"/>
  </input>
  ...
  <qemu:commandline>
    <qemu:arg value="-object"/>
    <qemu:arg value="input-linux,id=aio,evdev=/dev/input/by-id/virtual-event-EvdevProxyAIO,grab_all=yes,repeat=yes"/>
  </qemu:commandline>
</domain>

Of this in case of separate devices:

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  ...
  <input type="keyboard" bus="virtio">
    <address type="pci" domain="0x0000" bus="0x0a" slot="0x00" function="0x0"/>
  </input>
  <input type="mouse" bus="virtio">
    <address type="pci" domain="0x0000" bus="0x0b" slot="0x00" function="0x0"/>
  </input>
  ...
  <qemu:commandline>
    <qemu:arg value="-object"/>
    <qemu:arg value="input-linux,id=kbd,evdev=/dev/input/by-id/virtual-event-EvdevProxyKeyboard,grab_all=yes,repeat=yes"/>
    <qemu:arg value="-object"/>
    <qemu:arg value="input-linux,id=mouse,evdev=/dev/input/by-id/virtual-event-EvdevProxyMouse"/>
  </qemu:commandline>
</domain>

NOTE: Do not forget to add proper xmlns:qemu attribute to domain's root <domain> tag (see examples above).

On starting of qemu domain it should grab specified evdev devices. To switch between host and guest press both Right Ctrl and Left Ctrl keys (this is default qemu behavior). You can change default grab combination by adding grab-toggle parameter to input-linux object definition.

Currently supported values are:

  • ctrl-ctrl
  • alt-alt
  • meta-meta
  • scrolllock
  • ctrl-scrolllock

For example:

-object input-linux,id=aio,evdev=/dev/input/by-id/virtual-event-EvdevProxyAIO,grab_all=on,repeat=on,grab-toggle=alt-alt

For more information see following links:

Troubleshooting

Domain refuses to start

If for some reason domain refuses to start, complaining about missing evdev device, try following:

  • Ensure that /dev/uinput is accessible to the evdev-proxy.
  • Make sure that evdev-proxy is started, and check its logs for any errors regarding device creation.
  • If numerical evdev device (e.g /dev/input/eventN) is created, but no symlink is created for it in /dev/input/by-id/ make sure that you your virtual device name has EvdevProxy prefix in its name or create/edit corresponding udev rule in 70-uinput-evdev-proxy.rules file, or create your own.

Domain starts, but no keyboard/mouse in guest

If domains starts fine, but no events passed to guest domain try following:

  • Double-check that valid input-linux objects are passed to qemu command line (ps aux | grep qemu)
  • Check evdev-proxy logs for messages about source device captures (e.g Added new source dev "/dev/input/eventN"), also double-check selector parameters if config.toml.

Mouse/Keyboard goes crazy in guest

If you experience weird behaviour when trying to move the mouse and pressing keyboard keys simultaneously like spurious mouse movements and key presses try following:

  • Make sure that you added virtio-input input devices to domain configuration (see above)

  • Make sure that guest OS use those virtio-input devices instead of PS/2 emulation.

  • On linux you can check which devices xinput use, first get xinput IDs for those devices:

    xinput | grep -i virtio
    

    Then test that xinput events are coming from them:

    xinput test-xi2
    
  • On Windows make sure that virtio-input drivers are installed and devices are started properly in Device Manager. For latest/stable signed virtio drivers check fedora linux site.

evdev-proxy's People

Contributors

redrampage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

evdev-proxy's Issues

Fails to compile lexical-core dependency

I'm trying to test this out on a fedora 34 machine, and it fails to compile.

First failure is from compiling lexical-core which appears to be pulled in by the config crate:

error[E0308]: mismatched types
  --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/bhcomp.rs:62:24
   |
62 |     let bytes = bits / Limb::BITS;
   |                        ^^^^^^^^^^ expected `usize`, found `u32`

   Compiling regex v1.4.2
error[E0277]: cannot divide `usize` by `u32`
  --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/bhcomp.rs:62:22
   |
62 |     let bytes = bits / Limb::BITS;
   |                      ^ no implementation for `usize / u32`
   |
   = help: the trait `Div<u32>` is not implemented for `usize`

error[E0308]: mismatched types
   --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/bigcomp.rs:157:55
    |
157 |     let nlz = den.leading_zeros().wrapping_sub(wlz) & (u32::BITS - 1);
    |                                                       ^^^^^^^^^^^^^^^ expected `usize`, found `u32`

error[E0277]: no implementation for `usize & u32`
   --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/bigcomp.rs:157:53
    |
157 |     let nlz = den.leading_zeros().wrapping_sub(wlz) & (u32::BITS - 1);
    |                                                     ^ no implementation for `usize & u32`
    |
    = help: the trait `BitAnd<u32>` is not implemented for `usize`

error[E0308]: mismatched types
   --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/bigcomp.rs:175:40
    |
175 |         let (q, r) = shift.ceil_divmod(Limb::BITS);
    |                                        ^^^^^^^^^^ expected `usize`, found `u32`
    |
help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
    |
175 |         let (q, r) = shift.ceil_divmod(Limb::BITS.try_into().unwrap());
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   Compiling atty v0.2.14
error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1043:42
     |
1043 |     let mut count = index.saturating_mul(Limb::BITS);
     |                                          ^^^^^^^^^^ expected `usize`, found `u32`
     |
help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
     |
1043 |     let mut count = index.saturating_mul(Limb::BITS.try_into().unwrap());
     |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1058:28
     |
1058 |     Limb::BITS.checked_mul(x.len())
     |                            ^^^^^^^ expected `u32`, found `usize`
     |
help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
     |
1058 |     Limb::BITS.checked_mul(x.len().try_into().unwrap())
     |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1059:22
     |
1059 |         .map(|v| v - nlz)
     |                      ^^^ expected `u32`, found `usize`

error[E0277]: cannot subtract `usize` from `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1059:20
     |
1059 |         .map(|v| v - nlz)
     |                    ^ no implementation for `u32 - usize`
     |
     = help: the trait `Sub<usize>` is not implemented for `u32`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1060:20
     |
1060 |         .unwrap_or(usize::max_value())
     |                    ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize`
     |
help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
     |
1060 |         .unwrap_or(usize::max_value().try_into().unwrap())
     |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1058:5
     |
1054 |   pub fn bit_length(x: &[Limb]) -> usize {
     |                                    ----- expected `usize` because of return type
...
1058 | /     Limb::BITS.checked_mul(x.len())
1059 | |         .map(|v| v - nlz)
1060 | |         .unwrap_or(usize::max_value())
     | |______________________________________^ expected `usize`, found `u32`
     |
help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
     |
1058 |     Limb::BITS.checked_mul(x.len())
1059 |         .map(|v| v - nlz)
1060 |         .unwrap_or(usize::max_value()).try_into().unwrap()
     |

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1085:23
     |
1085 |     debug_assert!(n < bits && n != 0);
     |                       ^^^^ expected `usize`, found `u32`
     |
help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
     |
1085 |     debug_assert!(n < bits.try_into().unwrap() && n != 0);
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1092:25
     |
1092 |     let lshift = bits - n;
     |                         ^ expected `u32`, found `usize`

error[E0277]: cannot subtract `usize` from `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1092:23
     |
1092 |     let lshift = bits - n;
     |                       ^ no implementation for `u32 - usize`
     |
     = help: the trait `Sub<usize>` is not implemented for `u32`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1134:19
     |
1134 |     let rem = n % bits;
     |                   ^^^^ expected `usize`, found `u32`

error[E0277]: cannot mod `usize` by `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1134:17
     |
1134 |     let rem = n % bits;
     |                 ^ no implementation for `usize % u32`
     |
     = help: the trait `Rem<u32>` is not implemented for `usize`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1135:19
     |
1135 |     let div = n / bits;
     |                   ^^^^ expected `usize`, found `u32`

error[E0277]: cannot divide `usize` by `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1135:17
     |
1135 |     let div = n / bits;
     |                 ^ no implementation for `usize / u32`
     |
     = help: the trait `Div<u32>` is not implemented for `usize`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1191:23
     |
1191 |     debug_assert!(n < bits);
     |                       ^^^^ expected `usize`, found `u32`
     |
help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
     |
1191 |     debug_assert!(n < bits.try_into().unwrap());
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1201:25
     |
1201 |     let rshift = bits - n;
     |                         ^ expected `u32`, found `usize`

error[E0277]: cannot subtract `usize` from `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1201:23
     |
1201 |     let rshift = bits - n;
     |                       ^ no implementation for `u32 - usize`
     |
     = help: the trait `Sub<usize>` is not implemented for `u32`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1253:19
     |
1253 |     let rem = n % bits;
     |                   ^^^^ expected `usize`, found `u32`

error[E0277]: cannot mod `usize` by `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1253:17
     |
1253 |     let rem = n % bits;
     |                 ^ no implementation for `usize % u32`
     |
     = help: the trait `Rem<u32>` is not implemented for `usize`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1254:19
     |
1254 |     let div = n / bits;
     |                   ^^^^ expected `usize`, found `u32`

error[E0277]: cannot divide `usize` by `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:1254:17
     |
1254 |     let div = n / bits;
     |                 ^ no implementation for `usize / u32`
     |
     = help: the trait `Div<u32>` is not implemented for `usize`

error[E0308]: mismatched types
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:2065:27
     |
2065 |     let rs = Limb::BITS - s;
     |                           ^ expected `u32`, found `usize`

error[E0277]: cannot subtract `usize` from `u32`
    --> /home/jjongsma/.cargo/registry/src/github.com-1ecc6299db9ec823/lexical-core-0.7.4/src/atof/algorithm/math.rs:2065:25
     |
2065 |     let rs = Limb::BITS - s;
     |                         ^ no implementation for `u32 - usize`
     |
     = help: the trait `Sub<usize>` is not implemented for `u32`

error: aborting due to 27 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `lexical-core`

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.