Skip to content

Commit 54e5632

Browse files
joschockCopilot
andauthored
UefiHidDxeV2: Add keystroke repeat functionality (#883)
## Description Implement keyboard repeat for held keys, matching the behavior of the legacy C HidKeyboardDxe driver: - 500ms initial delay before repeat begins - 20ms repeat rate (~50 keys/sec) while key is held - Modifier keys, toggle keys, and non-spacing (dead) keys are excluded - Last newly pressed repeatable key wins in multi-key reports - Timer cancelled on key release or keyboard reset - [x] Impacts functionality? - [ ] Impacts security? - [ ] Breaking change? - [x] Includes tests? - [ ] Includes documentation? ## How This Was Tested Included unit tests, tested on hardware at UEFI shell and confirmed expected repeat behavior. ## Integration Instructions None. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 153d5cb commit 54e5632

5 files changed

Lines changed: 478 additions & 5 deletions

File tree

HidPkg/UefiHidDxeV2/src/boot_services.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pub trait UefiBootServices {
7979
controller_handle: efi::Handle,
8080
) -> efi::Status;
8181

82+
fn set_timer(&self, event: efi::Event, r#type: efi::TimerDelay, trigger_time: u64) -> efi::Status;
83+
8284
fn locate_protocol(
8385
&self,
8486
protocol: *mut efi::Guid,
@@ -195,6 +197,9 @@ impl UefiBootServices for StandardUefiBootServices {
195197
) -> efi::Status {
196198
(self.boot_services().locate_protocol)(protocol, registration, interface)
197199
}
200+
fn set_timer(&self, event: efi::Event, r#type: efi::TimerDelay, trigger_time: u64) -> efi::Status {
201+
(self.boot_services().set_timer)(event, r#type, trigger_time)
202+
}
198203
}
199204

200205
#[cfg(test)]
@@ -284,6 +289,10 @@ mod test {
284289
efi::Status::SUCCESS
285290
}
286291

292+
extern "efiapi" fn mock_set_timer(_event: efi::Event, _type: efi::TimerDelay, _trigger_time: u64) -> efi::Status {
293+
efi::Status::SUCCESS
294+
}
295+
287296
#[test]
288297
fn standard_uefi_boot_services_should_wrap_boot_services() {
289298
let boot_services = MaybeUninit::<efi::BootServices>::zeroed();
@@ -299,6 +308,7 @@ mod test {
299308
boot_services.open_protocol = mock_open_protocol;
300309
boot_services.close_protocol = mock_close_protocol;
301310
boot_services.locate_protocol = mock_locate_protocol;
311+
boot_services.set_timer = mock_set_timer;
302312

303313
const TEST_GUID: efi::Guid = efi::Guid::from_fields(0, 0, 0, 0, 0, &[0, 0, 0, 0, 0, 0]);
304314
let mut event = 1 as efi::Event;
@@ -373,5 +383,6 @@ mod test {
373383
),
374384
efi::Status::SUCCESS
375385
);
386+
assert_eq!(test_boot_services.set_timer(event, efi::TIMER_CANCEL, 0), efi::Status::SUCCESS);
376387
}
377388
}

0 commit comments

Comments
 (0)