Home | History | Annotate | Download | only in firmware_TouchMTB
      1 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """Keyboard device module to capture keyboard events."""
      6 
      7 import fcntl
      8 import os
      9 import re
     10 import sys
     11 
     12 sys.path.append('../../bin/input')
     13 import input_device
     14 
     15 import mtb
     16 
     17 from linux_input import EV_KEY
     18 
     19 
     20 class KeyboardDevice:
     21     """A class about keyboard device properties."""
     22     TYPE = '(keyboard|chromeos-ec-i2c|cros-ec-spi|cros-ec-i2c|cros_ec)'
     23 
     24     def __init__(self, device_node=None):
     25         self._device_info_file = '/proc/bus/input/devices'
     26         self.device_node = (device_node if device_node
     27                                         else self.get_device_node(self.TYPE))
     28         self.system_device = self._non_blocking_open(self.device_node)
     29         self._input_event = input_device.InputEvent()
     30 
     31     def __del__(self):
     32         self.system_device.close()
     33 
     34     def get_device_node(self, device_type):
     35         """Get the keyboard device node through device info file.
     36 
     37         Example of the keyboard device information looks like
     38 
     39         I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
     40         N: Name="AT Translated Set 2 keyboard"
     41         P: Phys=isa0060/serio0/input0
     42         S: Sysfs=/devices/platform/i8042/serio0/input/input5
     43         U: Uniq=
     44         H: Handlers=sysrq kbd event5
     45         """
     46         device_node = None
     47         device_found = None
     48         device_pattern = re.compile('N: Name=.*%s' % device_type, re.I)
     49         event_number_pattern = re.compile('H: Handlers=.*event(\d?)', re.I)
     50         with open(self._device_info_file) as info:
     51             for line in info:
     52                 if device_found:
     53                     result = event_number_pattern.search(line)
     54                     if result:
     55                         event_number = int(result.group(1))
     56                         device_node = '/dev/input/event%d' % event_number
     57                         break
     58                 else:
     59                     device_found = device_pattern.search(line)
     60         return device_node
     61 
     62     def exists(self):
     63         """Indicate whether this device exists or not."""
     64         return bool(self.device_node)
     65 
     66     def _non_blocking_open(self, filename):
     67         """Open the system file in the non-blocking mode."""
     68         fd = open(filename)
     69         fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
     70         return fd
     71 
     72     def _non_blocking_read(self, fd):
     73         """Non-blocking read on fd."""
     74         try:
     75             self._input_event.read(fd)
     76             return self._input_event
     77         except Exception:
     78             return None
     79 
     80     def get_key_press_event(self, fd):
     81         """Read the keyboard device node to get the key press events."""
     82         event = True
     83         # Read the device node continuously until either a key press event
     84         # is got or there is no more events to read.
     85         while event:
     86             event = self._non_blocking_read(fd)
     87             if event and event.type == EV_KEY and event.value == 1:
     88                 return event.code
     89         return None
     90