From 11a7e21c2adce7d81d82cc80ad84a4132251c376 Mon Sep 17 00:00:00 2001 From: Liav A Date: Wed, 1 Mar 2023 22:05:04 +0200 Subject: [PATCH] Kernel+Userland: Add support for using the PCSpeaker with various tones --- Base/usr/share/man/man1/beep.md | 7 +++++++ Kernel/Process.h | 2 +- Kernel/Syscalls/beep.cpp | 6 ++++-- Userland/Libraries/LibC/unistd.cpp | 4 ++-- Userland/Libraries/LibC/unistd.h | 2 +- Userland/Libraries/LibCore/System.cpp | 4 ++-- Userland/Libraries/LibCore/System.h | 2 +- Userland/Libraries/LibVT/TerminalWidget.cpp | 2 +- Userland/Utilities/beep.cpp | 9 +++++++-- 9 files changed, 26 insertions(+), 12 deletions(-) diff --git a/Base/usr/share/man/man1/beep.md b/Base/usr/share/man/man1/beep.md index 4995c0805b..146d13def0 100644 --- a/Base/usr/share/man/man1/beep.md +++ b/Base/usr/share/man/man1/beep.md @@ -12,6 +12,10 @@ $ beep beep allows the user to beep the PC speaker. +## Options + +* `-f|--beep-tone`: Beep tone (frequency in Hz) + ## Notes If the user disabled the usage of PC speaker in the kernel commandline, the program @@ -20,7 +24,10 @@ will fail to use the PC speaker. ## Examples ```sh +# Use beep with default tone $ beep +# Use beep with tone of 1000Hz +$ beep -f 1000 ``` ## See also diff --git a/Kernel/Process.h b/Kernel/Process.h index e7cbc3c54b..755b0fea9c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -291,7 +291,7 @@ public: ErrorOr sys$emuctl(); ErrorOr sys$yield(); ErrorOr sys$sync(); - ErrorOr sys$beep(); + ErrorOr sys$beep(int tone); ErrorOr sys$get_process_name(Userspace buffer, size_t buffer_size); ErrorOr sys$set_process_name(Userspace user_name, size_t user_name_length); ErrorOr sys$create_inode_watcher(u32 flags); diff --git a/Kernel/Syscalls/beep.cpp b/Kernel/Syscalls/beep.cpp index 0e6d4e37b5..bc9a4f24b0 100644 --- a/Kernel/Syscalls/beep.cpp +++ b/Kernel/Syscalls/beep.cpp @@ -12,13 +12,15 @@ namespace Kernel { -ErrorOr Process::sys$beep() +ErrorOr Process::sys$beep(int tone) { VERIFY_NO_PROCESS_BIG_LOCK(this); if (!kernel_command_line().is_pc_speaker_enabled()) return ENODEV; + if (tone < 20 || tone > 20000) + return EINVAL; #if ARCH(X86_64) - PCSpeaker::tone_on(440); + PCSpeaker::tone_on(tone); auto result = Thread::current()->sleep(Time::from_nanoseconds(200'000'000)); PCSpeaker::tone_off(); if (result.was_interrupted()) diff --git a/Userland/Libraries/LibC/unistd.cpp b/Userland/Libraries/LibC/unistd.cpp index 8eb0757148..c1b7531766 100644 --- a/Userland/Libraries/LibC/unistd.cpp +++ b/Userland/Libraries/LibC/unistd.cpp @@ -924,9 +924,9 @@ int gettid() return cached_tid; } -int sysbeep() +int sysbeep(int tone) { - int rc = syscall(SC_beep); + int rc = syscall(SC_beep, tone); __RETURN_WITH_ERRNO(rc, rc, -1); } diff --git a/Userland/Libraries/LibC/unistd.h b/Userland/Libraries/LibC/unistd.h index e01e9ef665..66b9a72132 100644 --- a/Userland/Libraries/LibC/unistd.h +++ b/Userland/Libraries/LibC/unistd.h @@ -35,7 +35,7 @@ int get_process_name(char* buffer, int buffer_size); int set_process_name(char const* name, size_t name_length); void dump_backtrace(void); int fsync(int fd); -int sysbeep(void); +int sysbeep(int tone); int gettid(void); int getpagesize(void); pid_t fork(void); diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 005b5597fb..9d7844d6cf 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -132,9 +132,9 @@ namespace Core::System { #ifdef AK_OS_SERENITY -ErrorOr beep() +ErrorOr beep(Optional tone) { - auto rc = ::sysbeep(); + auto rc = ::sysbeep(tone.value_or(440)); if (rc < 0) return Error::from_syscall("beep"sv, -errno); return {}; diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index 785ea92e9c..d3cc68baf3 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -43,7 +43,7 @@ namespace Core::System { #ifdef AK_OS_SERENITY -ErrorOr beep(); +ErrorOr beep(Optional tone); ErrorOr pledge(StringView promises, StringView execpromises = {}); ErrorOr unveil(StringView path, StringView permissions); ErrorOr unveil_after_exec(StringView path, StringView permissions); diff --git a/Userland/Libraries/LibVT/TerminalWidget.cpp b/Userland/Libraries/LibVT/TerminalWidget.cpp index 747f19a15e..46c46f2b85 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.cpp +++ b/Userland/Libraries/LibVT/TerminalWidget.cpp @@ -1067,7 +1067,7 @@ void TerminalWidget::beep() return; } if (m_bell_mode == BellMode::AudibleBeep) { - sysbeep(); + sysbeep(440); return; } m_visual_beep_timer->restart(200); diff --git a/Userland/Utilities/beep.cpp b/Userland/Utilities/beep.cpp index dc5314b363..eb765876cf 100644 --- a/Userland/Utilities/beep.cpp +++ b/Userland/Utilities/beep.cpp @@ -4,11 +4,16 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include -ErrorOr serenity_main(Main::Arguments) +ErrorOr serenity_main(Main::Arguments arguments) { - TRY(Core::System::beep()); + Optional tone; + Core::ArgsParser args_parser; + args_parser.add_option(tone, "Beep tone", "beep-tone", 'f', "Beep tone (frequency in Hz)"); + args_parser.parse(arguments); + TRY(Core::System::beep(tone)); return 0; }