Skip to content

Commit

Permalink
imp - Custom beep fixed for Linux
Browse files Browse the repository at this point in the history
---

We've fixed custom beep by resorting to the VT sequence.

---

Type: imp
Breaking: False
Doc Required: False
Backport Required: False
Part: 1/1
  • Loading branch information
AptiviCEO committed Jul 7, 2024
1 parent d98138f commit 14e0279
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 77 deletions.
5 changes: 4 additions & 1 deletion Terminaux/Base/ConsoleWrapperTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,10 @@ private static void BeepCustom(int freq, int ms)
if (PlatformHelper.IsOnWindows())
Console.Beep(freq, ms);
else
ConsoleMisc.CustomBeepPosix(freq, ms);
{
Write($"\x1b[10;{freq}]\x1b[11;{ms}]\a");
Thread.Sleep(ms);
}
}

private static void BeepSeq() =>
Expand Down
75 changes: 1 addition & 74 deletions Terminaux/Base/Extensions/ConsoleMisc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Terminaux.Base.Checks;
using Terminaux.Sequences;
using Terminaux.Writer.ConsoleWriters;
Expand Down Expand Up @@ -449,80 +450,6 @@ public static void ShowAltBuffer()
isOnAltBuffer = true;
}

internal static unsafe void CustomBeepPosix(int freq, int ms)
{
ms = ms < 0 ? 0 : ms;

// Inspired from https://github.com/johnath/beep
int fileDescriptor = -1;
string pathEv = "/dev/input/by-path/platform-pcspkr-event-spkr";
string pathVc = "/dev/vc/0";
string pathTty = "/dev/tty0";
IntPtr pathEvPtr = Marshal.StringToHGlobalAnsi(pathEv);
IntPtr pathVcPtr = Marshal.StringToHGlobalAnsi(pathVc);
IntPtr pathTtyPtr = Marshal.StringToHGlobalAnsi(pathTty);
if ((fileDescriptor = open(pathEvPtr, 1)) == -1)
if ((fileDescriptor = open(pathVcPtr, 1)) == -1)
fileDescriptor = open(pathTtyPtr, 1);
if (fileDescriptor == -1)
throw new TerminauxException("No more TTYs to perform custom beep. Make sure you have enough permissions.");

// Invoke the event to check to see if the console supports evdev or not by testing the
// _IOC(IOC.READ, 'E', 0x1a, len) ioctl
uint result = 0;
ulong eviocgSndTest = 0x40000000 | ((0 & 0x1fff) << 16) | (('E') << 8) | (0x1a);
bool isEvdev = ioctl(fileDescriptor, eviocgSndTest, ref result) != -1;

// Now, get the period that KIOCSOUND ioctl can understand
uint period = (uint)ms;
if (isEvdev)
{
var inputEvent = new input_event()
{
type = 0x12, // EV_SND
code = 0x02, // SND_TONE
value = freq
};
IntPtr eventPtr = new();
Marshal.StructureToPtr(inputEvent, eventPtr, true);
int writeResult = write(fileDescriptor, eventPtr, sizeof(input_event));
if (writeResult < 0)
throw new TerminauxException("Can't beep.");
}
else
{
ulong kiocSound = 0x4B2F;
int beepResult = ioctl(fileDescriptor, kiocSound, ref period);
if (beepResult < 0)
throw new TerminauxException("Can't beep.");
}
}

[StructLayout(LayoutKind.Sequential)]
private struct timeval
{
public int tv_sec;
public int tv_usec;
}

[StructLayout(LayoutKind.Sequential)]
private struct input_event
{
public timeval time;
public byte type;
public byte code;
public int value;
}

[DllImport("libc", SetLastError = true)]
internal static extern int write(int fd, IntPtr buf, int count);

[DllImport("libc", SetLastError = true)]
internal static extern int open(IntPtr pathname, int flags);

[DllImport("libc", SetLastError = true)]
internal static extern int ioctl(int fd, ulong request, ref uint argp);

static ConsoleMisc()
{
if (!ConsoleChecker.busy)
Expand Down
7 changes: 5 additions & 2 deletions Terminaux/Inputs/Pointer/PointerListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private static void StartListenerPosix()
// Test ioctl
ulong ctl = DetermineIoCtl();
uint numRead = 0;
int result = ConsoleMisc.ioctl(0, ctl, ref numRead);
int result = ioctl(0, ctl, ref numRead);
if (result == -1)
throw new TerminauxException("Failed to start the listener.");

Expand All @@ -211,7 +211,7 @@ private static void StartListenerPosix()
// Functions to help get output
int Peek(ref uint numRead, ref bool error)
{
int result = ConsoleMisc.ioctl(0, ctl, ref numRead);
int result = ioctl(0, ctl, ref numRead);
if (result == -1)
{
// Some failure occurred. Stop listening.
Expand Down Expand Up @@ -398,6 +398,9 @@ internal enum PosixButtonModifierState : uint
Alt = 0x0008,
Control = 0x0010,
}

[DllImport("libc", SetLastError = true)]
internal static extern int ioctl(int fd, ulong request, ref uint argp);
#endregion

#region Windows-specific
Expand Down

0 comments on commit 14e0279

Please sign in to comment.