From 0f89e47a1a7db411f5a9380aa5782b338ab80ea2 Mon Sep 17 00:00:00 2001 From: Spencer Dixon Date: Wed, 5 May 2021 17:10:56 -0400 Subject: [PATCH] Kernel: Allow remapping Caps Lock to Control (#6883) We use a global setting to determine if Caps Lock should be remapped to Control because we don't care how keyboard events come in, just that they should be massaged into different scan codes. The `proc` filesystem is able to manipulate this global variable using the `sysctl` utility like so: ``` # sysctl caps_lock_to_ctrl=1 ``` --- Kernel/Devices/HID/HIDManagement.cpp | 1 + Kernel/Devices/HID/HIDManagement.h | 3 +++ Kernel/Devices/HID/KeyboardDevice.cpp | 8 +++++++- Kernel/Devices/HID/KeyboardDevice.h | 1 + Kernel/FileSystem/ProcFS.cpp | 6 ++++++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Kernel/Devices/HID/HIDManagement.cpp b/Kernel/Devices/HID/HIDManagement.cpp index f110592833..faa9b6753c 100644 --- a/Kernel/Devices/HID/HIDManagement.cpp +++ b/Kernel/Devices/HID/HIDManagement.cpp @@ -12,6 +12,7 @@ namespace Kernel { +Atomic g_caps_lock_remapped_to_ctrl; static AK::Singleton s_the; // clang-format off diff --git a/Kernel/Devices/HID/HIDManagement.h b/Kernel/Devices/HID/HIDManagement.h index 6ab9694053..3ca0a8b458 100644 --- a/Kernel/Devices/HID/HIDManagement.h +++ b/Kernel/Devices/HID/HIDManagement.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -20,6 +21,8 @@ namespace Kernel { +extern Atomic g_caps_lock_remapped_to_ctrl; + class HIDDevice; class I8042Controller; class MouseDevice; diff --git a/Kernel/Devices/HID/KeyboardDevice.cpp b/Kernel/Devices/HID/KeyboardDevice.cpp index 0faa6e995e..f9e87e4ea7 100644 --- a/Kernel/Devices/HID/KeyboardDevice.cpp +++ b/Kernel/Devices/HID/KeyboardDevice.cpp @@ -234,9 +234,15 @@ void KeyboardDevice::key_state_changed(u8 scan_code, bool pressed) } } - if (key == Key_CapsLock && pressed) + if (!g_caps_lock_remapped_to_ctrl && key == Key_CapsLock && pressed) m_caps_lock_on = !m_caps_lock_on; + if (g_caps_lock_remapped_to_ctrl && key == Key_CapsLock) + m_caps_lock_to_ctrl_pressed = pressed; + + if (g_caps_lock_remapped_to_ctrl) + update_modifier(Mod_Ctrl, m_caps_lock_to_ctrl_pressed); + Event event; event.key = key; event.scancode = m_has_e0_prefix ? 0xe000 + scan_code : scan_code; diff --git a/Kernel/Devices/HID/KeyboardDevice.h b/Kernel/Devices/HID/KeyboardDevice.h index 9d1b9f689d..35585d6836 100644 --- a/Kernel/Devices/HID/KeyboardDevice.h +++ b/Kernel/Devices/HID/KeyboardDevice.h @@ -53,6 +53,7 @@ protected: virtual const char* class_name() const override { return "KeyboardDevice"; } u8 m_modifiers { 0 }; + bool m_caps_lock_to_ctrl_pressed { false }; bool m_caps_lock_on { false }; bool m_num_lock_on { false }; bool m_has_e0_prefix { false }; diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 8cbd49e493..07789b904a 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, Spencer Dixon * * SPDX-License-Identifier: BSD-2-Clause */ @@ -970,6 +971,7 @@ bool ProcFS::initialize() { static Lockable* kmalloc_stack_helper; static Lockable* ubsan_deadly_helper; + static Lockable* caps_lock_to_ctrl_helper; if (kmalloc_stack_helper == nullptr) { kmalloc_stack_helper = new Lockable(); @@ -982,6 +984,10 @@ bool ProcFS::initialize() ProcFS::add_sys_bool("ubsan_is_deadly", *ubsan_deadly_helper, [] { UBSanitizer::g_ubsan_is_deadly = ubsan_deadly_helper->resource(); }); + caps_lock_to_ctrl_helper = new Lockable(); + ProcFS::add_sys_bool("caps_lock_to_ctrl", *caps_lock_to_ctrl_helper, [] { + Kernel::g_caps_lock_remapped_to_ctrl.exchange(caps_lock_to_ctrl_helper->resource()); + }); } return true; }