svn commit: r281568 - stable/9/usr.sbin/bluetooth/bthidd
Raphael Kubo da Costa
rakuco at FreeBSD.org
Wed Apr 15 22:15:25 UTC 2015
Author: rakuco (ports committer)
Date: Wed Apr 15 22:15:23 2015
New Revision: 281568
URL: https://svnweb.freebsd.org/changeset/base/281568
Log:
MFC r281116.
bthidd: Consider usage ranges when dealing with array inputs.
So far, we were always using HID_USAGE() to determine the Usage ID of a
certain HID report input item. This does not work as intended if a field
is an array and the allowed usages are specified with a usage range, as
HID_USAGE() will return 0. We need to use the field value as an index in
the usage range list in this case instead.
This makes the volume keys in a Microsoft Bluetooth Mobile Keyboard
5000 be properly recognized. The relevant part of the HID report looks
like this:
0xA1, 0x01, // Collection (Application)
0x85, 0x07, // Report ID (7)
0x05, 0x0C, // Usage Page (Consumer)
0x19, 0x00, // Usage Minimum (Unassigned)
0x2A, 0xFF, 0x03, // Usage Maximum (0x03FF)
0x95, 0x01, // Report Count (1)
0x75, 0x10, // Report Size (16)
0x15, 0x00, // Logical Minimum (0)
0x27, 0xFF, 0x03, 0x00, 0x00, // Logical Maximum (1023)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred
// State,No Null Position)
When a key such as "volume down" is pressed, the following data is
transferred through Interrupt In:
0x07 0xEA 0x00
Differential Revision: https://reviews.freebsd.org/D2229
Reviewed by: emax
Approved by: emax
Modified:
stable/9/usr.sbin/bluetooth/bthidd/hid.c
Directory Properties:
stable/9/usr.sbin/bluetooth/bthidd/ (props changed)
Modified: stable/9/usr.sbin/bluetooth/bthidd/hid.c
==============================================================================
--- stable/9/usr.sbin/bluetooth/bthidd/hid.c Wed Apr 15 22:07:51 2015 (r281567)
+++ stable/9/usr.sbin/bluetooth/bthidd/hid.c Wed Apr 15 22:15:23 2015 (r281568)
@@ -165,9 +165,21 @@ hid_interrupt(bthid_session_p s, uint8_t
continue;
page = HID_PAGE(h.usage);
- usage = HID_USAGE(h.usage);
val = hid_get_data(data, &h);
+ /*
+ * When the input field is an array and the usage is specified
+ * with a range instead of an ID, we have to derive the actual
+ * usage by using the item value as an index in the usage range
+ * list.
+ */
+ if ((h.flags & HIO_VARIABLE)) {
+ usage = HID_USAGE(h.usage);
+ } else {
+ const uint32_t usage_offset = val - h.logical_minimum;
+ usage = HID_USAGE(h.usage_minimum + usage_offset);
+ }
+
switch (page) {
case HUP_GENERIC_DESKTOP:
switch (usage) {
More information about the svn-src-stable-9
mailing list