From ce6658acc130a83f6a4468a8ec547f403ac7d042 Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Sat, 3 Jul 2021 19:41:28 -0400 Subject: [PATCH] KeyboardSettings+Kernel: Setting to enable Num Lock on login --- Kernel/API/Syscall.h | 1 + Kernel/CMakeLists.txt | 1 + Kernel/Devices/HID/HIDManagement.cpp | 5 +++++ Kernel/Devices/HID/HIDManagement.h | 1 + Kernel/Devices/HID/KeyboardDevice.h | 2 ++ Kernel/Process.h | 1 + Kernel/Syscalls/num_lock.cpp | 18 ++++++++++++++++++ .../Applications/KeyboardSettings/main.cpp | 17 ++++++++++++++++- Userland/Libraries/LibC/serenity.cpp | 5 +++++ Userland/Libraries/LibC/serenity.h | 2 ++ .../Services/KeyboardPreferenceLoader/main.cpp | 6 ++++++ 11 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 Kernel/Syscalls/num_lock.cpp diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 50d7e28721..616b47f9f4 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -143,6 +143,7 @@ namespace Kernel { S(getrandom) \ S(getkeymap) \ S(setkeymap) \ + S(set_num_lock) \ S(clock_gettime) \ S(clock_settime) \ S(clock_nanosleep) \ diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 0f8116ec36..b2807dc8e0 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -191,6 +191,7 @@ set(KERNEL_SOURCES Syscalls/mmap.cpp Syscalls/module.cpp Syscalls/mount.cpp + Syscalls/num_lock.cpp Syscalls/open.cpp Syscalls/perf_event.cpp Syscalls/pipe.cpp diff --git a/Kernel/Devices/HID/HIDManagement.cpp b/Kernel/Devices/HID/HIDManagement.cpp index 67c2073007..2eaa7e2f01 100644 --- a/Kernel/Devices/HID/HIDManagement.cpp +++ b/Kernel/Devices/HID/HIDManagement.cpp @@ -98,6 +98,11 @@ void HIDManagement::set_maps(const Keyboard::CharacterMapData& character_map_dat dbgln("New Character map '{}' passed in by client.", character_map_name); } +void HIDManagement::set_num_lock(bool on) +{ + m_i8042_controller->keyboard()->set_num_lock(on); +} + UNMAP_AFTER_INIT void HIDManagement::enumerate() { // FIXME: When we have USB HID support, we should ensure that we disable diff --git a/Kernel/Devices/HID/HIDManagement.h b/Kernel/Devices/HID/HIDManagement.h index 954e0d1af6..0249ab94e7 100644 --- a/Kernel/Devices/HID/HIDManagement.h +++ b/Kernel/Devices/HID/HIDManagement.h @@ -45,6 +45,7 @@ public: const Keyboard::CharacterMap& character_map() const { return m_character_map; } void set_client(KeyboardClient* client) { m_client = client; } void set_maps(const Keyboard::CharacterMapData& character_map, const String& character_map_name); + void set_num_lock(bool on); private: size_t generate_minor_device_number_for_mouse(); diff --git a/Kernel/Devices/HID/KeyboardDevice.h b/Kernel/Devices/HID/KeyboardDevice.h index 28a9a77d35..15faa7db91 100644 --- a/Kernel/Devices/HID/KeyboardDevice.h +++ b/Kernel/Devices/HID/KeyboardDevice.h @@ -45,6 +45,8 @@ public: m_modifiers &= ~modifier; } + void set_num_lock(bool on) { m_num_lock_on = on; } + protected: KeyboardDevice(); mutable SpinLock m_queue_lock; diff --git a/Kernel/Process.h b/Kernel/Process.h index 69220fe7fe..b8aaa1e6fe 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -291,6 +291,7 @@ public: KResultOr sys$getresuid(Userspace, Userspace, Userspace); KResultOr sys$getresgid(Userspace, Userspace, Userspace); KResultOr sys$umask(mode_t); + KResultOr sys$set_num_lock(bool); KResultOr sys$open(Userspace); KResultOr sys$close(int fd); KResultOr sys$read(int fd, Userspace, size_t); diff --git a/Kernel/Syscalls/num_lock.cpp b/Kernel/Syscalls/num_lock.cpp new file mode 100644 index 0000000000..aff6d60ff1 --- /dev/null +++ b/Kernel/Syscalls/num_lock.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Kernel { + +KResultOr Process::sys$set_num_lock(bool on) +{ + HIDManagement::the().set_num_lock(on); + return 0; +} + +} diff --git a/Userland/Applications/KeyboardSettings/main.cpp b/Userland/Applications/KeyboardSettings/main.cpp index 96aa443701..d587d42889 100644 --- a/Userland/Applications/KeyboardSettings/main.cpp +++ b/Userland/Applications/KeyboardSettings/main.cpp @@ -8,12 +8,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -33,11 +35,17 @@ int main(int argc, char** argv) // If there is no command line parameter go for GUI. auto app = GUI::Application::construct(argc, argv); - if (pledge("stdio rpath recvfd sendfd proc exec", nullptr) < 0) { + if (pledge("stdio rpath cpath wpath recvfd sendfd proc exec", nullptr) < 0) { perror("pledge"); return 1; } + auto config = Core::ConfigFile::get_for_app("KeyboardSettings"); + if (unveil(config->filename().characters(), "rwc") < 0) { + perror("unveil"); + return 1; + } + if (unveil("/res", "r") < 0) { perror("unveil"); return 1; @@ -117,6 +125,9 @@ int main(int argc, char** argv) character_map_file_combo.set_model(*CharacterMapFileListModel::create(character_map_files)); character_map_file_combo.set_selected_index(initial_keymap_index); + auto& num_lock_checkbox = root_widget.add("Enable Num Lock on login"); + num_lock_checkbox.set_checked(config->read_bool_entry("StartupEnable", "NumLock", true)); + root_widget.layout()->add_spacer(); auto apply_settings = [&](bool quit) { @@ -131,6 +142,10 @@ int main(int argc, char** argv) perror("posix_spawn"); exit(1); } + + config->write_bool_entry("StartupEnable", "NumLock", num_lock_checkbox.is_checked()); + config->sync(); + if (quit) app->quit(); }; diff --git a/Userland/Libraries/LibC/serenity.cpp b/Userland/Libraries/LibC/serenity.cpp index 0f112ca0ae..e819b20d62 100644 --- a/Userland/Libraries/LibC/serenity.cpp +++ b/Userland/Libraries/LibC/serenity.cpp @@ -137,6 +137,11 @@ int getkeymap(char* name_buffer, size_t name_buffer_size, u32* map, u32* shift_m __RETURN_WITH_ERRNO(rc, rc, -1); } +void set_num_lock(bool on) +{ + syscall(SC_set_num_lock, on); +} + u16 internet_checksum(const void* ptr, size_t count) { u32 checksum = 0; diff --git a/Userland/Libraries/LibC/serenity.h b/Userland/Libraries/LibC/serenity.h index 0557a10f78..db5b261c33 100644 --- a/Userland/Libraries/LibC/serenity.h +++ b/Userland/Libraries/LibC/serenity.h @@ -105,6 +105,8 @@ int serenity_readlink(const char* path, size_t path_length, char* buffer, size_t int getkeymap(char* name_buffer, size_t name_buffer_size, uint32_t* map, uint32_t* shift_map, uint32_t* alt_map, uint32_t* altgr_map, uint32_t* shift_altgr_map); int setkeymap(const char* name, const uint32_t* map, uint32_t* const shift_map, const uint32_t* alt_map, const uint32_t* altgr_map, const uint32_t* shift_altgr_map); +void set_num_lock(bool on); + uint16_t internet_checksum(const void* ptr, size_t count); __END_DECLS diff --git a/Userland/Services/KeyboardPreferenceLoader/main.cpp b/Userland/Services/KeyboardPreferenceLoader/main.cpp index 16fb65d06d..acebe25edf 100644 --- a/Userland/Services/KeyboardPreferenceLoader/main.cpp +++ b/Userland/Services/KeyboardPreferenceLoader/main.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,8 @@ int main() return 1; } + auto keyboard_settings_config = Core::ConfigFile::get_for_app("KeyboardSettings"); + if (unveil("/bin/keymap", "x") < 0) { perror("unveil /bin/keymap"); return 1; @@ -41,4 +44,7 @@ int main() perror("posix_spawn"); exit(1); } + + bool enable_num_lock = keyboard_settings_config->read_bool_entry("StartupEnable", "NumLock", true); + set_num_lock(enable_num_lock); }