Commit 4ff8f3ee authored by spang's avatar spang Committed by Commit bot

ozone: evdev: Add absolute axis information to DeviceCapabilities

We'll need this to do touchscreen (and other absolute) device testing
with real event dumps as input since the axis information must be valid.

Replace the shell script to capture capabilities with a python script,
because the absolute axis bounds aren't exposed in sysfs. We have
python-evdev on test images. Unfortunately it's a bit incomplete & buggy,
so fall back to sysfs for the missing & incorrect bits.

The "sw" field was accidently omitted previously and is now populated.

BUG=none
TEST=events_unittests

Review URL: https://codereview.chromium.org/1019793011

Cr-Commit-Position: refs/heads/master@{#322384}
parent a71414d3
#!/usr/bin/python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Code generator DeviceCapabilities literal."""
import argparse
import ctypes
import evdev
import os
import sys
TEST_DATA_GROUP_SIZE = 64 # Aligns with sysfs on 64-bit devices.
def bits_to_groups(bits):
return (bits + TEST_DATA_GROUP_SIZE - 1) / TEST_DATA_GROUP_SIZE
# As in /sys/class/input/input*/capabilities/*
def serialize_bitfield(bitfield, max_bit):
result = ""
group_count = bits_to_groups(max_bit)
for group in xrange(group_count - 1, -1, -1):
group_val = 0
for group_bit in xrange(TEST_DATA_GROUP_SIZE):
code = group * TEST_DATA_GROUP_SIZE + group_bit
if code in bitfield:
group_val |= (1 << group_bit)
if group_val or result:
result += '%x' % group_val
if group:
result += ' '
if not result:
return '0'
return result
def dump_absinfo(out, capabilities, identifier):
out.write('const DeviceAbsoluteAxis %s[] = {\n' % identifier)
for code, absinfo in capabilities[evdev.ecodes.EV_ABS]:
# Set value := 0 to make it deterministic.
code_name = evdev.ecodes.bytype[evdev.ecodes.EV_ABS][code]
absinfo_struct = (0, absinfo.min, absinfo.max, absinfo.fuzz, absinfo.flat,
absinfo.resolution)
data = (code_name,) + absinfo_struct
out.write(' {%s, {%d, %d, %d, %d, %d, %d}},\n' % data)
out.write('};\n')
def dump_capabilities(out, dev, identifier):
capabilities = dev.capabilities()
has_abs = evdev.ecodes.EV_ABS in capabilities
sysfs_path = '/sys/class/input/' + os.path.basename(dev.fn)
# python-evdev is missing some features
uniq = open(sysfs_path + '/device/uniq', 'r').read().strip()
prop = open(sysfs_path + '/device/properties', 'r').read().strip()
ff = open(sysfs_path + '/device/capabilities/ff', 'r').read().strip()
# python-evdev parses the id wrong.
bustype = open(sysfs_path + '/device/id/bustype', 'r').read().strip()
vendor = open(sysfs_path + '/device/id/vendor', 'r').read().strip()
product = open(sysfs_path + '/device/id/product', 'r').read().strip()
version = open(sysfs_path + '/device/id/version', 'r').read().strip()
# python-evdev drops EV_REP from the event set.
ev = open(sysfs_path + '/device/capabilities/ev', 'r').read().strip()
if ctypes.sizeof(ctypes.c_long()) != 8:
# /sys/class/input/*/properties format is word size dependent.
# Could be fixed by regrouping but for now, just raise an error.
raise ValueError("Must be run on 64-bit machine")
key_bits = capabilities.get(evdev.ecodes.EV_KEY, [])
rel_bits = capabilities.get(evdev.ecodes.EV_REL, [])
abs_bits = [abs[0] for abs in capabilities.get(evdev.ecodes.EV_ABS, [])]
msc_bits = capabilities.get(evdev.ecodes.EV_MSC, [])
sw_bits = capabilities.get(evdev.ecodes.EV_SW, [])
led_bits = capabilities.get(evdev.ecodes.EV_LED, [])
fields = [
('path', os.path.realpath(sysfs_path)),
('name', dev.name),
('phys', dev.phys),
('uniq', uniq),
('bustype', bustype),
('vendor', vendor),
('product', product),
('version', version),
('prop', prop),
('ev', ev),
('key', serialize_bitfield(key_bits, evdev.ecodes.KEY_CNT)),
('rel', serialize_bitfield(rel_bits, evdev.ecodes.REL_CNT)),
('abs', serialize_bitfield(abs_bits, evdev.ecodes.ABS_CNT)),
('msc', serialize_bitfield(msc_bits, evdev.ecodes.MSC_CNT)),
('sw', serialize_bitfield(sw_bits, evdev.ecodes.SW_CNT)),
('led', serialize_bitfield(led_bits, evdev.ecodes.LED_CNT)),
('ff', ff),
]
if has_abs:
absinfo_identifier = identifier + 'AbsAxes'
dump_absinfo(out, capabilities, absinfo_identifier)
out.write('const DeviceCapabilities %s = {\n' % identifier)
for name, val in fields:
out.write(' /* %s */ "%s",\n' % (name, val))
if has_abs:
out.write(' %s,\n' % absinfo_identifier)
out.write(' arraysize(%s),\n' % absinfo_identifier)
out.write('};\n')
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('device')
parser.add_argument('identifier')
args = parser.parse_args(argv)
dev = evdev.InputDevice(args.device)
out = sys.stdout
dump_capabilities(out, dev, args.identifier)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
...@@ -76,30 +76,6 @@ bool ParseBitfield(const std::string& bitfield, ...@@ -76,30 +76,6 @@ bool ParseBitfield(const std::string& bitfield,
} // namespace } // namespace
// # Script to generate DeviceCapabilities literal.
// cd /sys/class/input/input?
//
// test "$(uname -m)" = x86_64 && cat <<EOF
// const DeviceCapabilities device = {
// /* path */ "$(readlink -f .)",
// /* name */ "$(cat device/name)",
// /* phys */ "$(cat device/phys)",
// /* uniq */ "$(cat device/uniq)",
// /* bustype */ "$(cat device/id/bustype)",
// /* vendor */ "$(cat device/id/vendor)",
// /* product */ "$(cat device/id/product)",
// /* version */ "$(cat device/id/version)",
// /* prop */ "$(cat device/properties)",
// /* ev */ "$(cat device/capabilities/ev)",
// /* key */ "$(cat device/capabilities/key)",
// /* rel */ "$(cat device/capabilities/rel)",
// /* abs */ "$(cat device/capabilities/abs)",
// /* msc */ "$(cat device/capabilities/msc)",
// /* led */ "$(cat device/capabilities/led)",
// /* ff */ "$(cat device/capabilities/ff)",
// };
// EOF
// Captured from Chromebook Pixel. // Captured from Chromebook Pixel.
const DeviceCapabilities kLinkKeyboard = { const DeviceCapabilities kLinkKeyboard = {
/* path */ "/sys/devices/platform/i8042/serio0/input/input6/event6", /* path */ "/sys/devices/platform/i8042/serio0/input/input6/event6",
...@@ -116,11 +92,24 @@ const DeviceCapabilities kLinkKeyboard = { ...@@ -116,11 +92,24 @@ const DeviceCapabilities kLinkKeyboard = {
/* rel */ "0", /* rel */ "0",
/* abs */ "0", /* abs */ "0",
/* msc */ "10", /* msc */ "10",
/* sw */ "0",
/* led */ "7", /* led */ "7",
/* ff */ "0", /* ff */ "0",
}; };
// Captured from Chromebook Pixel. // Captured from Chromebook Pixel.
const DeviceAbsoluteAxis kLinkTouchscreenAbsAxes[] = {
{ABS_X, {0, 0, 2559, 0, 0, 20}},
{ABS_Y, {0, 0, 1699, 0, 0, 20}},
{ABS_PRESSURE, {0, 0, 255, 0, 0, 0}},
{ABS_MT_SLOT, {0, 0, 15, 0, 0, 0}},
{ABS_MT_TOUCH_MAJOR, {0, 0, 938, 0, 0, 0}},
{ABS_MT_ORIENTATION, {0, -3, 4, 0, 0, 0}},
{ABS_MT_POSITION_X, {0, 0, 2559, 0, 0, 20}},
{ABS_MT_POSITION_Y, {0, 0, 1699, 0, 0, 20}},
{ABS_MT_TRACKING_ID, {0, 0, 65535, 0, 0, 0}},
{ABS_MT_PRESSURE, {0, 0, 255, 0, 0, 0}},
};
const DeviceCapabilities kLinkTouchscreen = { const DeviceCapabilities kLinkTouchscreen = {
/* path */ "/sys/devices/pci0000:00/0000:00:02.0/i2c-2/2-004a/" /* path */ "/sys/devices/pci0000:00/0000:00:02.0/i2c-2/2-004a/"
"input/input7/event7", "input/input7/event7",
...@@ -137,11 +126,26 @@ const DeviceCapabilities kLinkTouchscreen = { ...@@ -137,11 +126,26 @@ const DeviceCapabilities kLinkTouchscreen = {
/* rel */ "0", /* rel */ "0",
/* abs */ "671800001000003", /* abs */ "671800001000003",
/* msc */ "0", /* msc */ "0",
/* sw */ "0",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
kLinkTouchscreenAbsAxes,
arraysize(kLinkTouchscreenAbsAxes),
}; };
// Captured from Chromebook Pixel. // Captured from Chromebook Pixel.
const DeviceAbsoluteAxis kLinkTouchpadAbsAxes[] = {
{ABS_X, {0, 0, 2040, 0, 0, 20}},
{ABS_Y, {0, 0, 1360, 0, 0, 20}},
{ABS_PRESSURE, {0, 0, 255, 0, 0, 0}},
{ABS_MT_SLOT, {0, 0, 9, 0, 0, 0}},
{ABS_MT_TOUCH_MAJOR, {0, 0, 1878, 0, 0, 0}},
{ABS_MT_ORIENTATION, {0, -3, 4, 0, 0, 0}},
{ABS_MT_POSITION_X, {0, 0, 2040, 0, 0, 20}},
{ABS_MT_POSITION_Y, {0, 0, 1360, 0, 0, 20}},
{ABS_MT_TRACKING_ID, {0, 0, 65535, 0, 0, 0}},
{ABS_MT_PRESSURE, {0, 0, 255, 0, 0, 0}},
};
const DeviceCapabilities kLinkTouchpad = { const DeviceCapabilities kLinkTouchpad = {
/* path */ "/sys/devices/pci0000:00/0000:00:02.0/i2c-1/1-004b/" /* path */ "/sys/devices/pci0000:00/0000:00:02.0/i2c-1/1-004b/"
"input/input8/event8", "input/input8/event8",
...@@ -158,8 +162,11 @@ const DeviceCapabilities kLinkTouchpad = { ...@@ -158,8 +162,11 @@ const DeviceCapabilities kLinkTouchpad = {
/* rel */ "0", /* rel */ "0",
/* abs */ "671800001000003", /* abs */ "671800001000003",
/* msc */ "0", /* msc */ "0",
/* sw */ "0",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
kLinkTouchpadAbsAxes,
arraysize(kLinkTouchpadAbsAxes),
}; };
// Captured from generic HP KU-1156 USB keyboard. // Captured from generic HP KU-1156 USB keyboard.
...@@ -180,11 +187,15 @@ const DeviceCapabilities kHpUsbKeyboard = { ...@@ -180,11 +187,15 @@ const DeviceCapabilities kHpUsbKeyboard = {
/* rel */ "0", /* rel */ "0",
/* abs */ "0", /* abs */ "0",
/* msc */ "10", /* msc */ "10",
/* sw */ "0",
/* led */ "7", /* led */ "7",
/* ff */ "0", /* ff */ "0",
}; };
// Captured from generic HP KU-1156 USB keyboard (2nd device with media keys). // Captured from generic HP KU-1156 USB keyboard (2nd device with media keys).
const DeviceAbsoluteAxis kHpUsbKeyboard_ExtraAbsAxes[] = {
{ABS_VOLUME, {0, 0, 767, 0, 0, 0}},
};
const DeviceCapabilities kHpUsbKeyboard_Extra = { const DeviceCapabilities kHpUsbKeyboard_Extra = {
/* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/" /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.1/"
"input/input18/event16", "input/input18/event16",
...@@ -202,8 +213,11 @@ const DeviceCapabilities kHpUsbKeyboard_Extra = { ...@@ -202,8 +213,11 @@ const DeviceCapabilities kHpUsbKeyboard_Extra = {
/* rel */ "40", /* rel */ "40",
/* abs */ "100000000", /* abs */ "100000000",
/* msc */ "10", /* msc */ "10",
/* sw */ "0",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
kHpUsbKeyboard_ExtraAbsAxes,
arraysize(kHpUsbKeyboard_ExtraAbsAxes),
}; };
// Captured from Dell MS111-L 3-Button Optical USB Mouse. // Captured from Dell MS111-L 3-Button Optical USB Mouse.
...@@ -223,11 +237,16 @@ const DeviceCapabilities kLogitechUsbMouse = { ...@@ -223,11 +237,16 @@ const DeviceCapabilities kLogitechUsbMouse = {
/* rel */ "143", /* rel */ "143",
/* abs */ "0", /* abs */ "0",
/* msc */ "10", /* msc */ "10",
/* sw */ "0",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
}; };
// Captured from "Mimo Touch 2" Universal DisplayLink monitor. // Captured from "Mimo Touch 2" Universal DisplayLink monitor.
const DeviceAbsoluteAxis kMimoTouch2TouchscreenAbsAxes[] = {
{ABS_X, {0, 0, 2047, 0, 0, 0}},
{ABS_Y, {0, 0, 2047, 0, 0, 0}},
};
const DeviceCapabilities kMimoTouch2Touchscreen = { const DeviceCapabilities kMimoTouch2Touchscreen = {
/* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3.2/" /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3.2/"
"2-1.3.2:1.0/input/input15/event14", "2-1.3.2:1.0/input/input15/event14",
...@@ -244,11 +263,20 @@ const DeviceCapabilities kMimoTouch2Touchscreen = { ...@@ -244,11 +263,20 @@ const DeviceCapabilities kMimoTouch2Touchscreen = {
/* rel */ "0", /* rel */ "0",
/* abs */ "3", /* abs */ "3",
/* msc */ "0", /* msc */ "0",
/* sw */ "0",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
kMimoTouch2TouchscreenAbsAxes,
arraysize(kMimoTouch2TouchscreenAbsAxes),
}; };
// Captured from Wacom Intuos Pen and Touch Small Tablet. // Captured from Wacom Intuos Pen and Touch Small Tablet.
const DeviceAbsoluteAxis kWacomIntuosPtS_PenAbsAxes[] = {
{ABS_X, {0, 0, 15200, 4, 0, 100}},
{ABS_Y, {0, 0, 9500, 4, 0, 100}},
{ABS_PRESSURE, {0, 0, 1023, 0, 0, 0}},
{ABS_DISTANCE, {0, 0, 31, 0, 0, 0}},
};
const DeviceCapabilities kWacomIntuosPtS_Pen = { const DeviceCapabilities kWacomIntuosPtS_Pen = {
/* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/" /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/"
"2-1.2.3:1.0/input/input9/event9", "2-1.2.3:1.0/input/input9/event9",
...@@ -265,11 +293,24 @@ const DeviceCapabilities kWacomIntuosPtS_Pen = { ...@@ -265,11 +293,24 @@ const DeviceCapabilities kWacomIntuosPtS_Pen = {
/* rel */ "0", /* rel */ "0",
/* abs */ "3000003", /* abs */ "3000003",
/* msc */ "0", /* msc */ "0",
/* sw */ "0",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
kWacomIntuosPtS_PenAbsAxes,
arraysize(kWacomIntuosPtS_PenAbsAxes),
}; };
// Captured from Wacom Intuos Pen and Touch Small Tablet. // Captured from Wacom Intuos Pen and Touch Small Tablet.
const DeviceAbsoluteAxis kWacomIntuosPtS_FingerAbsAxes[] = {
{ABS_X, {0, 0, 4096, 4, 0, 26}},
{ABS_Y, {0, 0, 4096, 4, 0, 43}},
{ABS_MT_SLOT, {0, 0, 15, 0, 0, 0}},
{ABS_MT_TOUCH_MAJOR, {0, 0, 4096, 0, 0, 0}},
{ABS_MT_TOUCH_MINOR, {0, 0, 4096, 0, 0, 0}},
{ABS_MT_POSITION_X, {0, 0, 4096, 4, 0, 26}},
{ABS_MT_POSITION_Y, {0, 0, 4096, 4, 0, 43}},
{ABS_MT_TRACKING_ID, {0, 0, 65535, 0, 0, 0}},
};
const DeviceCapabilities kWacomIntuosPtS_Finger = { const DeviceCapabilities kWacomIntuosPtS_Finger = {
/* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/" /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/"
"2-1.2.3:1.1/input/input10/event10", "2-1.2.3:1.1/input/input10/event10",
...@@ -286,11 +327,17 @@ const DeviceCapabilities kWacomIntuosPtS_Finger = { ...@@ -286,11 +327,17 @@ const DeviceCapabilities kWacomIntuosPtS_Finger = {
/* rel */ "0", /* rel */ "0",
/* abs */ "263800000000003", /* abs */ "263800000000003",
/* msc */ "0", /* msc */ "0",
/* sw */ "4000",
/* led */ "0", /* led */ "0",
/* ff */ "0", /* ff */ "0",
kWacomIntuosPtS_FingerAbsAxes,
arraysize(kWacomIntuosPtS_FingerAbsAxes),
}; };
// Captured from Logitech Wireless Touch Keyboard K400. // Captured from Logitech Wireless Touch Keyboard K400.
const DeviceAbsoluteAxis kLogitechTouchKeyboardK400AbsAxes[] = {
{ABS_VOLUME, {0, 1, 652, 0, 0, 0}},
};
const DeviceCapabilities kLogitechTouchKeyboardK400 = { const DeviceCapabilities kLogitechTouchKeyboardK400 = {
/* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/" /* path */ "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2.3/"
"2-1.2.3:1.2/0003:046D:C52B.0006/input/input19/event17", "2-1.2.3:1.2/0003:046D:C52B.0006/input/input19/event17",
...@@ -309,8 +356,11 @@ const DeviceCapabilities kLogitechTouchKeyboardK400 = { ...@@ -309,8 +356,11 @@ const DeviceCapabilities kLogitechTouchKeyboardK400 = {
/* rel */ "1c3", /* rel */ "1c3",
/* abs */ "100000000", /* abs */ "100000000",
/* msc */ "10", /* msc */ "10",
/* sw */ "0",
/* led */ "1f", /* led */ "1f",
/* ff */ "0", /* ff */ "0",
kLogitechTouchKeyboardK400AbsAxes,
arraysize(kLogitechTouchKeyboardK400AbsAxes),
}; };
bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities, bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities,
...@@ -350,6 +400,11 @@ bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities, ...@@ -350,6 +400,11 @@ bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities,
return false; return false;
devinfo->SetProps(&prop_bits[0], prop_bits.size()); devinfo->SetProps(&prop_bits[0], prop_bits.size());
for (size_t i = 0; i < capabilities.abs_axis_count; ++i) {
const DeviceAbsoluteAxis& axis = capabilities.abs_axis[i];
devinfo->SetAbsInfo(axis.code, axis.absinfo);
}
return true; return true;
} }
......
...@@ -5,10 +5,17 @@ ...@@ -5,10 +5,17 @@
#ifndef UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_TEST_UTIL_H_ #ifndef UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_TEST_UTIL_H_
#define UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_TEST_UTIL_H_ #define UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_TEST_UTIL_H_
#include <linux/input.h>
namespace ui { namespace ui {
class EventDeviceInfo; class EventDeviceInfo;
struct DeviceAbsoluteAxis {
unsigned int code;
input_absinfo absinfo;
};
struct DeviceCapabilities { struct DeviceCapabilities {
// Full sysfs path (readlink -f /sys/class/input/event*) // Full sysfs path (readlink -f /sys/class/input/event*)
const char* path; const char* path;
...@@ -42,6 +49,10 @@ struct DeviceCapabilities { ...@@ -42,6 +49,10 @@ struct DeviceCapabilities {
const char* sw; const char* sw;
const char* led; const char* led;
const char* ff; const char* ff;
// EVIOCGABS.
const DeviceAbsoluteAxis* abs_axis;
size_t abs_axis_count;
}; };
bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities, bool CapabilitiesToDeviceInfo(const DeviceCapabilities& capabilities,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment