mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 08:24:58 +00:00

There's no need to have separate syscall for this kind of functionality, as we can just have a device node in /dev, called "beep", that allows writing tone generation packets to emulate the same behavior. In addition to that, we remove LibC sysbeep function, as this function was never being used by any C program nor it was standardized in any way. Instead, we move the userspace implementation to LibCore.
63 lines
1.8 KiB
C++
63 lines
1.8 KiB
C++
/*
|
|
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <Kernel/API/BeepInstruction.h>
|
|
#if ARCH(X86_64)
|
|
# include <Kernel/Arch/x86_64/PCSpeaker.h>
|
|
#endif
|
|
#include <Kernel/Boot/CommandLine.h>
|
|
#include <Kernel/Devices/DeviceManagement.h>
|
|
#include <Kernel/Devices/Generic/PCSpeakerDevice.h>
|
|
#include <Kernel/Sections.h>
|
|
|
|
namespace Kernel {
|
|
|
|
UNMAP_AFTER_INIT NonnullRefPtr<PCSpeakerDevice> PCSpeakerDevice::must_create()
|
|
{
|
|
auto device = MUST(DeviceManagement::try_create_device<PCSpeakerDevice>());
|
|
return *device;
|
|
}
|
|
|
|
UNMAP_AFTER_INIT PCSpeakerDevice::PCSpeakerDevice()
|
|
: CharacterDevice(1, 10)
|
|
{
|
|
}
|
|
|
|
UNMAP_AFTER_INIT PCSpeakerDevice::~PCSpeakerDevice() = default;
|
|
|
|
bool PCSpeakerDevice::can_read(OpenFileDescription const&, u64) const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
ErrorOr<size_t> PCSpeakerDevice::read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t)
|
|
{
|
|
return Error::from_errno(ENOTIMPL);
|
|
}
|
|
|
|
ErrorOr<size_t> PCSpeakerDevice::write(OpenFileDescription&, u64, UserOrKernelBuffer const& buffer, size_t buffer_size)
|
|
{
|
|
if (!kernel_command_line().is_pc_speaker_enabled())
|
|
return Error::from_errno(ENOTSUP);
|
|
if (buffer_size % sizeof(BeepInstruction) != 0)
|
|
return Error::from_errno(EINVAL);
|
|
BeepInstruction instruction {};
|
|
TRY(buffer.read(&instruction, sizeof(BeepInstruction)));
|
|
if (instruction.tone < 20 || instruction.tone > 20000)
|
|
return Error::from_errno(EINVAL);
|
|
#if ARCH(X86_64)
|
|
PCSpeaker::tone_on(instruction.tone);
|
|
auto result = Thread::current()->sleep(Duration::from_nanoseconds(200'000'000));
|
|
PCSpeaker::tone_off();
|
|
if (result.was_interrupted())
|
|
return Error::from_errno(EINTR);
|
|
return sizeof(BeepInstruction);
|
|
#else
|
|
return Error::from_errno(ENOTIMPL);
|
|
#endif
|
|
}
|
|
|
|
}
|