Add evdev passthru.

This commit is contained in:
SimonFair
2024-05-06 20:44:44 +01:00
parent 072e3512e0
commit b4a3a90a46
4 changed files with 163 additions and 1 deletions

View File

@@ -1,6 +1,6 @@
Menu="VMs:0"
Title="VM Usage Statisics"
Nchan="vm_usage:stop"
Nchan="vm_usage"
Cond="exec(\"grep -o '^USAGE=.Y' /boot/config/domain.cfg 2>/dev/null\") && is_file('/var/run/libvirt/libvirtd.pid')"
---
<?PHP

View File

@@ -290,6 +290,7 @@
$audios = $config['audio'];
$template = $config['template'];
$clocks = $config['clock'];
$evdevs = $config['evdev'];
$type = $domain['type'];
$name = $domain['name'];
@@ -998,6 +999,16 @@
</memballoon>";
}
#$osbootdev = "" ;
$evdevstr = "";
foreach($evdevs as $evdev) {
if ($evdev['dev'] == "") continue;
$evdevstr .= "<input type='evdev'>\n<source dev='{$evdev['dev']}'";
if ($evdev['grab'] != "") $evdevstr .= " grab='{$evdev['grab']}' ";
if ($evdev['grabToggle'] != "") $evdevstr .= " grabToggle='{$evdev['grabToggle']}' ";
if ($evdev['repeat'] != "") $evdevstr .= " repeat='{$evdev['repeat']}' ";
$evdevstr .= "/>\n</input>\n";
}
$memorybackingXML = Array2XML::createXML('memoryBacking', $memorybacking);
$memoryBackingXML = $memorybackingXML->saveXML($memorybackingXML->documentElement);
return "<domain type='$type' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
@@ -1043,6 +1054,7 @@
$channelscopypaste
$swtpm
$memballoon
$evdevstr
</devices>
</domain>";

View File

@@ -931,6 +931,19 @@ private static $encoding = 'UTF-8';
return $arrValidOtherStubbedDevices;
}
function getValidevDev() {
$inputevdev = array_merge(glob("/dev/input/by-id/*event-kbd"),glob("/dev/input/by-id/*event-mouse"));
return $inputevdev;
}
function getevDev($res) {
global $lv ;
$xml = $lv->domain_get_xml($res) ;
$xmldoc = new SimpleXMLElement($xml);
$xmlpath = $xmldoc->xpath('//devices/input[@type="evdev"] ');
return $xmlpath;
}
$cacheValidUSBDevices = null;
function getValidUSBDevices() {
global $cacheValidUSBDevices;
@@ -1375,6 +1388,7 @@ private static $encoding = 'UTF-8';
'nic' => $arrNICs,
'usb' => $arrUSBDevs,
'shares' => $lv->domain_get_mount_filesystems($res),
'evdev' => getevDev($res),
'qemucmdline' => $cmdline,
'clocks' => getClocks($strDOMXML)
];
@@ -1427,6 +1441,7 @@ private static $encoding = 'UTF-8';
}
// settings not in the GUI, but maybe customized
unset($old['clock']);
unset($old['devices']['input']);
// preserve vnc/spice port settings
// unset($new['devices']['graphics']['@attributes']['port'],$new['devices']['graphics']['@attributes']['autoport']);
if (!$new['devices']['graphics']) unset($old['devices']['graphics']);

View File

@@ -1626,6 +1626,141 @@
<p>Windows and Hyperv Hpet:no Hypervclock: yes Pit no rtc no. </p>
</p>
</blockquote>
<?#echo "<span>".var_dump($arrConfig['evdev'])."</span>";
if ( $arrConfig['evdev'] == false) {
$evdevxml = "<input type='evdev'>
<source dev=''/>
</input>";
$evdevdoc = new SimpleXMLElement($evdevxml);
$arrConfig['evdev']= $evdevdoc->xpath('//input[@type="evdev"] ');
}
foreach ($arrConfig['evdev'] as $i => $arrEvdev) {
$strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : '';
?>
<table data-category="Input" data-multiple="true" data-minimum="1" data-index="<?=$i?>" data-prefix="<?=$strLabel?>">
<tr>
<td>_(Evdev Device)_:</td>
<td>
<select name="evdev[<?=$i?>][dev]" class="dev narrow">
<?
echo mk_option($arrEvdev->source->attributes()->dev, '', _('None'));
foreach(getValidevDev() as $line) echo mk_option($arrEvdev->source->attributes()->dev, $line , $line);
?>
</select>
</td>
<tr class="advanced disk_file_options">
<td>_(Grab)_:</td>
<td>
<select name="evdev[<?=$i?>][grab]" class="evdev_grab" title="_(grab options)_">
<?echo mk_option($arrEvdev->source->attributes()->grab, '', _('None'));
foreach(["all"] as $line) echo mk_option($arrEvdev->source->attributes()->grab,$line,ucfirst($line));?>
</select>
</td>
</tr>
<tr class="advanced disk_file_options">
<td>_(Repeat)_:</td>
<td>
<select name="evdev[<?=$i?>][repeat]" class="evdev_repeat narrow" title="_(grab options)_">
<?echo mk_option($arrEvdev->source->attributes()->repeat, '', _('None'));
foreach(["on","off"] as $line) echo mk_option($arrEvdev->source->attributes()->repeat,$line,ucfirst($line));?>
</select>
</td>
</tr>
<tr class="advanced disk_file_options">
<td>_(Grab Toggle)_:</td>
<td>
<select name="evdev[<?=$i?>][grabToggle]" class="evdev_grabtoggle narrow" title="_(grab options)_">
<?echo mk_option($arrEvdev->source->attributes()->grabToggle, '', _('None'));
foreach(["ctrl-ctrl", "alt-alt", "shift-shift", "meta-meta", "scrolllock" , "ctrl-scrolllock"] as $line) echo mk_option($arrEvdev->source->attributes()->grabToggle,$line,$line);?>
</select>
</td>
</tr>
</table>
<?if ($i == 0) {?>
<div class="advanced">
<blockquote class="inline_help">
<p>
<b> Event Devices</b><br>
Evdev is an input interface built into the Linux kernel. QEMUs evdev passthrough support allows a user to redirect evdev events to a guest. These events can include mouse movements and key presses. By hitting both Ctrl keys at the same time, QEMU can toggle the input recipient. QEMUs evdev passthrough also features almost no latency, making it perfect for gaming. The main downside to evdev passthrough is the lack of button rebinding and in some cases, macro keys wont even work at all.
Optional items are normally only used for keyboards.
</p>
<p>
<b>Device</b><br>
Host device to passthrough to guest.
</p>
<p>
<b>Grab</b><br>
All grabs all input devices instead of just one
</p>
<p>
<b>Repeat</b><br>
Repeat with value 'on'/'off' to enable/disable auto-repeat events
</p>
<p>
<b>GrabToggle</b><br>
GrabToggle with values ctrl-ctrl, alt-alt, shift-shift, meta-meta, scrolllock or ctrl-scrolllock to change the grab key combination</p>
<p>Additional devices can be added/removed by clicking the symbols to the left.</p>
</blockquote>
</div>
<?}?>
<?}?>
<script type="text/html" id="tmplevdev">
<table data-category="Input" data-multiple="true" data-minimum="1" data-index="<?=$i?>" data-prefix="<?=$strLabel?>">
<tr>
<td>_(Evdev Device)_:</td>
<td>
<select name="evdev[{{INDEX}}][dev]" class="dev narrow">
<?
echo mk_option("", '', _('None'));
foreach(getValidevDev() as $line) echo mk_option("", $line , $line);
?>
</select>
</td>
<tr class="advanced disk_file_options">
<td>_(Grab)_:</td>
<td>
<select name="evdev[{{INDEX}}][grab]" class="evdev_grab" title="_(grab options)_">
<?echo mk_option("" , '', _('None'));
foreach(["all"] as $line) echo mk_option("",$line,ucfirst($line));?>
</select>
</td>
</tr>
<tr class="advanced disk_file_options">
<td>_(Repeat)_:</td>
<td>
<select name="evdev[{{INDEX}}][repeat]" class="evdev_repeat narrow" title="_(grab options)_">
<?echo mk_option("", '', _('None'));
foreach(["on","off"] as $line) echo mk_option("",$line,ucfirst($line));?>
</select>
</td>
</tr>
<tr class="advanced disk_file_options">
<td>_(Grab Toggle)_:</td>
<td>
<select name="evdev[{{INDEX}}][grabToggle]" class="evdev_grabtoggle narrow" title="_(grab options)_">
<?echo mk_option("", '', _('None'));
foreach(["ctrl-ctrl", "alt-alt", "shift-shift", "meta-meta", "scrolllock" , "ctrl-scrolllock"] as $line) echo mk_option("",$line,$line);?>
</select>
</td>
</tr>
</table>
</script>
<table>
<tr>