blob: 0d421c876b673e3def8007a401913e6522c54f3b [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Keyboard device module to capture keyboard events."""
import fcntl
import os
import re
import sys
sys.path.append('../../bin/input')
import input_device
import mtb
from linux_input import EV_KEY
class KeyboardDevice:
"""A class about keyboard device properties."""
TYPE = '(keyboard|chromeos-ec-i2c|cros-ec-spi|cros-ec-i2c)'
def __init__(self, device_node=None):
self._device_info_file = '/proc/bus/input/devices'
self.device_node = (device_node if device_node
else self.get_device_node(self.TYPE))
self.system_device = self._non_blocking_open(self.device_node)
self._input_event = input_device.InputEvent()
def __del__(self):
self.system_device.close()
def get_device_node(self, device_type):
"""Get the keyboard device node through device info file.
Example of the keyboard device information looks like
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input5
U: Uniq=
H: Handlers=sysrq kbd event5
"""
device_node = None
device_found = None
device_pattern = re.compile('N: Name=.*%s' % device_type, re.I)
event_number_pattern = re.compile('H: Handlers=.*event(\d?)', re.I)
with open(self._device_info_file) as info:
for line in info:
if device_found:
result = event_number_pattern.search(line)
if result:
event_number = int(result.group(1))
device_node = '/dev/input/event%d' % event_number
break
else:
device_found = device_pattern.search(line)
return device_node
def exists(self):
"""Indicate whether this device exists or not."""
return bool(self.device_node)
def _non_blocking_open(self, filename):
"""Open the system file in the non-blocking mode."""
fd = open(filename)
fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
return fd
def _non_blocking_read(self, fd):
"""Non-blocking read on fd."""
try:
self._input_event.read(fd)
return self._input_event
except Exception:
return None
def get_key_press_event(self, fd):
"""Read the keyboard device node to get the key press events."""
event = True
# Read the device node continuously until either a key press event
# is got or there is no more events to read.
while event:
event = self._non_blocking_read(fd)
if event and event.type == EV_KEY and event.value == 1:
return event.code
return None