Add support for customizable grabToggle key combinations with
<input type='evdev'>.
Signed-off-by: Justin Gatzen <justin.gatzen(a)gmail.com>
---
docs/formatdomain.rst | 12 +++++++-----
docs/schemas/domaincommon.rng | 12 ++++++++++++
src/conf/domain_conf.c | 19 +++++++++++++++++++
src/conf/domain_conf.h | 14 ++++++++++++++
src/libvirt_private.syms | 2 ++
src/qemu/qemu_command.c | 5 +++++
.../input-linux.x86_64-latest.args | 2 +-
tests/qemuxml2argvdata/input-linux.xml | 2 +-
8 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index b621591515..61ccd8895a 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -5747,7 +5747,7 @@ to provide a graphics tablet for absolute cursor movement.
<source evdev='/dev/input/event1'/>
</input>
<input type='evdev'>
- <source dev='/dev/input/event1234' grab='all'
repeat='on'/>
+ <source dev='/dev/input/event1234' grab='all'
repeat='on' grabToggle='ctrl-ctrl'/>
</input>
</devices>
...
@@ -5768,10 +5768,12 @@ On S390, ``address`` can be used to provide a CCW address for an
input device (
sub-element ``source`` must have an ``evdev`` (for ``passthrough``) or ``dev``
(for ``evdev``) attribute containing the absolute path to the event device
passed through to guests.
-For type ``evdev``, ``source`` can have two optional attributes ``grab`` with
-value 'all' which when enabled grabs all input devices instead of just one and
-``repeat`` with value 'on'/'off' to enable/disable auto-repeat events (
-:since:`Since 7.4.0`).
+For type ``evdev``, ``source`` has three optional attributes ``grab`` with
+value 'all' which when enabled grabs all input devices instead of just one,
+``repeat`` with value 'on'/'off' to enable/disable auto-repeat events
and
+``grabToggle`` (:since:`since 7.6.0`) with values ``ctrl-ctrl``, ``alt-alt``,
+``shift-shift``, ``meta-meta``, ``scrolllock`` or ``ctrl-scrolllock`` to
+change the grab key combination.
``input`` type ``evdev`` is currently supported only on linux devices.
(KVM only) :since:`Since 5.2.0` , the ``input`` element accepts a
``model`` attribute which has the values 'virtio', 'virtio-transitional'
and
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 538581360d..14c5d4ee68 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5484,6 +5484,18 @@
<value>all</value>
</attribute>
</optional>
+ <optional>
+ <attribute name="grabToggle">
+ <choice>
+ <value>ctrl-ctrl</value>
+ <value>alt-alt</value>
+ <value>shift-shift</value>
+ <value>meta-meta</value>
+ <value>scrolllock</value>
+ <value>ctrl-scrolllock</value>
+ </choice>
+ </attribute>
+ </optional>
<optional>
<attribute name="repeat">
<ref name="virOnOff"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e05ea9ba88..44d55ede5b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -891,6 +891,17 @@ VIR_ENUM_IMPL(virDomainInputSourceGrab,
"all",
);
+VIR_ENUM_IMPL(virDomainInputSourceGrabToggle,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_LAST,
+ "default",
+ "ctrl-ctrl",
+ "alt-alt",
+ "shift-shift",
+ "meta-meta",
+ "scrolllock",
+ "ctrl-scrolllock",
+);
+
VIR_ENUM_IMPL(virDomainGraphics,
VIR_DOMAIN_GRAPHICS_TYPE_LAST,
"sdl",
@@ -12011,6 +12022,11 @@ virDomainInputDefParseXML(virDomainXMLOption *xmlopt,
VIR_XML_PROP_NONZERO, &def->source.grab) < 0)
goto error;
+ if (virXMLPropEnum(source, "grabToggle",
+ virDomainInputSourceGrabToggleTypeFromString,
+ VIR_XML_PROP_NONZERO, &def->source.grabToggle) <
0)
+ goto error;
+
if (virXMLPropTristateSwitch(source, "repeat",
VIR_XML_PROP_NONE, &def->source.repeat)
< 0)
goto error;
@@ -25998,6 +26014,7 @@ virDomainInputDefFormat(virBuffer *buf,
const char *type = virDomainInputTypeToString(def->type);
const char *bus = virDomainInputBusTypeToString(def->bus);
const char *grab = virDomainInputSourceGrabTypeToString(def->source.grab);
+ const char *grabToggle =
virDomainInputSourceGrabToggleTypeToString(def->source.grabToggle);
const char *repeat = virTristateSwitchTypeToString(def->source.repeat);
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
@@ -26049,6 +26066,8 @@ virDomainInputDefFormat(virBuffer *buf,
if (def->source.grab)
virBufferAsprintf(&sourceAttrBuf, " grab='%s'", grab);
+ if (def->source.grabToggle)
+ virBufferAsprintf(&sourceAttrBuf, " grabToggle='%s'",
grabToggle);
if (def->source.repeat)
virBufferAsprintf(&sourceAttrBuf, " repeat='%s'", repeat);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5c22f252d0..ca21082624 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1420,6 +1420,18 @@ typedef enum {
VIR_DOMAIN_INPUT_SOURCE_GRAB_LAST
} virDomainInputSourceGrab;
+typedef enum {
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_DEFAULT,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_CTRL_CTRL,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_ALT_ALT,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_SHIFT_SHIFT,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_META_META,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_SCROLLLOCK,
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_CTRL_SCROLLLOCK,
+
+ VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_LAST
+} virDomainInputSourceGrabToggle;
+
struct _virDomainInputDef {
int type;
int bus;
@@ -1427,6 +1439,7 @@ struct _virDomainInputDef {
struct {
char *evdev;
virDomainInputSourceGrab grab;
+ virDomainInputSourceGrabToggle grabToggle;
virTristateSwitch repeat;
} source;
virDomainDeviceInfo info;
@@ -3871,6 +3884,7 @@ VIR_ENUM_DECL(virDomainInput);
VIR_ENUM_DECL(virDomainInputBus);
VIR_ENUM_DECL(virDomainInputModel);
VIR_ENUM_DECL(virDomainInputSourceGrab);
+VIR_ENUM_DECL(virDomainInputSourceGrabToggle);
VIR_ENUM_DECL(virDomainGraphics);
VIR_ENUM_DECL(virDomainGraphicsListen);
VIR_ENUM_DECL(virDomainGraphicsAuthConnected);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4bc2974e7f..6bbf551f48 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -476,6 +476,8 @@ virDomainInputBusTypeToString;
virDomainInputDefFind;
virDomainInputDefFree;
virDomainInputDefGetPath;
+virDomainInputSourceGrabToggleTypeFromString;
+virDomainInputSourceGrabToggleTypeToString;
virDomainInputSourceGrabTypeFromString;
virDomainInputSourceGrabTypeToString;
virDomainInputTypeToString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3c3ecd63e3..156af4caee 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3947,6 +3947,11 @@ qemuBuildObjectInputDevStr(virDomainInputDef *dev,
if (dev->source.grab == VIR_DOMAIN_INPUT_SOURCE_GRAB_ALL)
virJSONValueObjectAdd(props, "b:grab_all", true, NULL);
+ if (dev->source.grabToggle != VIR_DOMAIN_INPUT_SOURCE_GRAB_TOGGLE_DEFAULT)
+ virJSONValueObjectAdd(props, "s:grab-toggle",
+
virDomainInputSourceGrabToggleTypeToString(dev->source.grabToggle),
+ NULL);
+
if (qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps) < 0)
return NULL;
diff --git a/tests/qemuxml2argvdata/input-linux.x86_64-latest.args
b/tests/qemuxml2argvdata/input-linux.x86_64-latest.args
index 688cf02873..3c7e65a7f0 100644
--- a/tests/qemuxml2argvdata/input-linux.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/input-linux.x86_64-latest.args
@@ -27,7 +27,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
-no-acpi \
-boot strict=on \
-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
--object
'{"qom-type":"input-linux","id":"input0","evdev":"/dev/input/event1234","repeat":true,"grab_all":true}'
\
+-object
'{"qom-type":"input-linux","id":"input0","evdev":"/dev/input/event1234","repeat":true,"grab_all":true,"grab-toggle":"alt-alt"}'
\
-audiodev id=audio1,driver=none \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxml2argvdata/input-linux.xml
b/tests/qemuxml2argvdata/input-linux.xml
index c0702676c1..389ba789a6 100644
--- a/tests/qemuxml2argvdata/input-linux.xml
+++ b/tests/qemuxml2argvdata/input-linux.xml
@@ -22,7 +22,7 @@
<address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
</controller>
<input type='evdev'>
- <source dev='/dev/input/event1234' grab='all'
repeat='on'/>
+ <source dev='/dev/input/event1234' grab='all'
grabToggle='alt-alt' repeat='on'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
--
2.32.0