Skip to content

Commit

Permalink
Add support for Digitizer touch input usages as pointer buttons (#496)
Browse files Browse the repository at this point in the history
## Description

This PR adds support for Digitizer switch usages (HID Usage Page 0xD,
usages 0x42 through 0x46) as buttons in the AbsolutePointer
implementation.

See https://usb.org/document-library/hid-usage-tables-15 for usage
tables.

- [x] Impacts functionality?
- Add support for Digitizer switch usages as buttons in the pointer
interface.
- [ ] Impacts security?
- [ ] Breaking change?
- [ ] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

Functionally verified with a touch panel implementation that exposes
these HID usages.

## Integration Instructions

No special integration required.
  • Loading branch information
joschock authored Jun 17, 2024
1 parent 2d6746b commit f7327e7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
8 changes: 6 additions & 2 deletions HidPkg/UefiHidDxeV2/src/pointer/absolute_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rust_advanced_logger_dxe::{debugln, DEBUG_ERROR, DEBUG_INFO, DEBUG_WARN};

use crate::boot_services::UefiBootServices;

use super::PointerHidHandler;
use super::{PointerHidHandler, BUTTON_MAX, BUTTON_MIN, DIGITIZER_SWITCH_MAX, DIGITIZER_SWITCH_MIN};

// FFI context
// Safety: a pointer to PointerHidHandler is included in the context so that it can be reclaimed in the absolute_pointer
Expand Down Expand Up @@ -129,7 +129,11 @@ impl PointerContext {
debugln!(DEBUG_INFO, "No z-axis usages found in the report descriptor.");
}

let button_count = pointer_handler.supported_usages.iter().filter(|x| x.page() == super::BUTTON_PAGE).count();
let button_count = pointer_handler
.supported_usages
.iter()
.filter(|x| matches!((**x).into(), BUTTON_MIN..=BUTTON_MAX | DIGITIZER_SWITCH_MIN..=DIGITIZER_SWITCH_MAX))
.count();

if button_count > 1 {
mode.attributes |= 0x01; // alternate button exists.
Expand Down
18 changes: 12 additions & 6 deletions HidPkg/UefiHidDxeV2/src/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ const GENERIC_DESKTOP_X: u32 = 0x00010030;
const GENERIC_DESKTOP_Y: u32 = 0x00010031;
const GENERIC_DESKTOP_Z: u32 = 0x00010032;
const GENERIC_DESKTOP_WHEEL: u32 = 0x00010038;
const BUTTON_PAGE: u16 = 0x0009;
const BUTTON_MIN: u32 = 0x00090001;
const BUTTON_MAX: u32 = 0x00090020; //Per spec, the Absolute Pointer protocol supports a 32-bit button state field.
const DIGITIZER_SWITCH_MIN: u32 = 0x000d0042;
const DIGITIZER_SWITCH_MAX: u32 = 0x000d0046;

// number of points on the X/Y axis for this implementation.
const AXIS_RESOLUTION: u64 = 1024;
Expand Down Expand Up @@ -127,6 +128,11 @@ impl PointerHidHandler {
report_data.relevant_fields.push(field_handler);
self.supported_usages.insert(field.usage);
}
DIGITIZER_SWITCH_MIN..=DIGITIZER_SWITCH_MAX => {
let field_handler = ReportFieldWithHandler { field: field.clone(), report_handler: Self::button_handler };
report_data.relevant_fields.push(field_handler);
self.supported_usages.insert(field.usage);
}
_ => (), //other usages irrelevant
}
}
Expand Down Expand Up @@ -197,15 +203,15 @@ impl PointerHidHandler {

// handles button inputs
fn button_handler(&mut self, field: VariableField, report: &[u8]) {
let shift: u32 = field.usage.into();
if !(BUTTON_MIN..=BUTTON_MAX).contains(&shift) {
return;
}
let shift = match field.usage.into() {
x @ BUTTON_MIN..=BUTTON_MAX => x - BUTTON_MIN,
x @ DIGITIZER_SWITCH_MIN..=DIGITIZER_SWITCH_MAX => x - DIGITIZER_SWITCH_MIN,
_ => return,
};

if let Some(button_value) = field.field_value(report) {
let button_value = button_value as u32;

let shift = shift - BUTTON_MIN;
if shift > u32::BITS {
return;
}
Expand Down

0 comments on commit f7327e7

Please sign in to comment.