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
7import fcntl
8import os
9import re
10import sys
11
12sys.path.append('../../bin/input')
13import input_device
14
15import mtb
16
17from linux_input import EV_KEY
18
19
20class KeyboardDevice:
21    """A class about keyboard device properties."""
22
23    def __init__(self, device_node=None):
24        if device_node:
25            self.device_node = device_node
26        else:
27            self.device_node = input_device.get_device_node(
28                    input_device.KEYBOARD_TYPES))
29        self.system_device = self._non_blocking_open(self.device_node)
30        self._input_event = input_device.InputEvent()
31
32    def __del__(self):
33        self.system_device.close()
34
35    def exists(self):
36        """Indicate whether this device exists or not."""
37        return bool(self.device_node)
38
39    def _non_blocking_open(self, filename):
40        """Open the system file in the non-blocking mode."""
41        fd = open(filename)
42        fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
43        return fd
44
45    def _non_blocking_read(self, fd):
46        """Non-blocking read on fd."""
47        try:
48            self._input_event.read(fd)
49            return self._input_event
50        except Exception:
51            return None
52
53    def get_key_press_event(self, fd):
54        """Read the keyboard device node to get the key press events."""
55        event = True
56        # Read the device node continuously until either a key press event
57        # is got or there is no more events to read.
58        while event:
59            event = self._non_blocking_read(fd)
60            if event and event.type == EV_KEY and event.value == 1:
61                return event.code
62        return None
63