Skip to content

Commit

Permalink
scan /dev/input for device detection
Browse files Browse the repository at this point in the history
  • Loading branch information
JarbasAl committed Oct 17, 2022
1 parent cc7550b commit 4c4fa92
Showing 1 changed file with 72 additions and 21 deletions.
93 changes: 72 additions & 21 deletions ovos_utils/device_input.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import os
import subprocess
from distutils.spawn import find_executable

from ovos_utils.log import LOG


class InputDeviceHelper:
def __init__(self) -> None:
self.input_devices_list = []
if not find_executable("libinput"):
raise Exception("libinput executable not found")
self.libinput_devices_list = []
self.xinput_devices_list = []
self.dev_input_devices_list = []
if not find_executable("libinput") and not find_executable("xinput"):
LOG.warning("Could not find libinput or xinput, input device detection will be inaccurate")

# ToDo: add support for discovring the input device based of a connected
# monitors, currently linux only supports input listing directly from the
# system

def build_input_devices_list(self):
def _build_linput_devices_list(self):
# Always clear the list before building it
self.input_devices_list.clear()
self.libinput_devices_list.clear()

input_device_names = []
input_device_kernel_path = []
input_device_group = []
input_device_capabilities = []

# Get the list of devices from libinput
proc_output = subprocess.check_output(
['libinput', 'list-devices']).decode('utf-8')
proc_output = subprocess.check_output(['libinput', 'list-devices']).decode('utf-8')
for line in proc_output.splitlines():
if line.startswith('Device'):
unformated_device_name = line.split(':')[1]
Expand Down Expand Up @@ -58,33 +61,77 @@ def build_input_devices_list(self):
unformated_device_capabilities)

for i in range(len(input_device_names)):
self.input_devices_list.append(
self.libinput_devices_list.append(
{"Device": input_device_names[i],
"Kernel": input_device_kernel_path[i],
"Group": input_device_group[i],
"Capabilities": input_device_capabilities[i]
})

def get_input_devices_list(self):
self.build_input_devices_list()
return self.input_devices_list
def _get_libinput_devices_list(self):
self._build_linput_devices_list()
return self.libinput_devices_list

def can_use_touch_mouse(self):
def _build_xinput_devices_list(self):
# Always clear the list before building it
self.xinput_devices_list.clear()

# Get the list of devices from xinput
proc_output = subprocess.check_output(['xinput', 'list']).decode('utf-8')
for line in proc_output.splitlines():
if "id=" not in line:
continue
line = line.replace("↳", "").replace("⎡", "").replace("⎣", "").replace("⎜", "").strip()

if "pointer" in line:
dev = {"Device": line.split("id=")[0].strip(),
"Capabilities": ["mouse"]}
self.xinput_devices_list.append(dev)
if "keyboard" in line:
dev = {"Device": line.split("id=")[0].strip(),
"Capabilities": ["keyboard"]}
self.xinput_devices_list.append(dev)

def _get_xinput_devices_list(self):
self._build_xinput_devices_list()
return self.xinput_devices_list

def _build_dev_input_devices_list(self):
# Always clear the list before building it
self.dev_input_devices_list.clear()

# Get the list of devices from naive scanning of /dev/input
for d in os.listdir("/dev/input"):
if d.startswith("mouse") or d.startswith("mice"):
dev = {"Device": d,
"Capabilities": ["mouse"]}
self.dev_input_devices_list.append(dev)

def get_input_device_list(self):
# check if any of the devices support touch or mouse
self.build_input_devices_list()
for device in self.input_devices_list:
if "touch" in device["Capabilities"] or "mouse" in device[
"Capabilities"] or "tablet" in device["Capabilities"] or "gesture" in device["Capabilities"]:
return True
if find_executable("libinput"):
self._build_linput_devices_list()
if find_executable("xinput"):
self._build_xinput_devices_list()
self._build_dev_input_devices_list()

return self.libinput_devices_list + \
self.xinput_devices_list + \
self.dev_input_devices_list

def can_use_touch_mouse(self):
for device in self.get_input_device_list():
if "touch" in device["Capabilities"] or \
"mouse" in device["Capabilities"] or \
"tablet" in device["Capabilities"] or \
"gesture" in device["Capabilities"]:
return True
return False

def can_use_keyboard(self):
self.build_input_devices_list()
for device in self.input_devices_list:
for device in self.get_input_device_list():
if "keyboard" in device["Capabilities"]:
return True

return False


Expand All @@ -94,3 +141,7 @@ def can_use_touch_mouse():

def can_use_keyboard():
return InputDeviceHelper().can_use_keyboard()


if __name__ == "__main__":
can_use_touch_mouse()

0 comments on commit 4c4fa92

Please sign in to comment.