Initial commit
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RobotNet10.RobotApp.Natives;
|
||||
|
||||
/// <summary>
|
||||
/// Native declarations for Linux evdev (event device) input subsystem.
|
||||
/// Used for low-latency keyboard input reading from /dev/input/event* devices.
|
||||
/// </summary>
|
||||
internal static partial class EvdevNative
|
||||
{
|
||||
// Event types
|
||||
public const ushort EV_SYN = 0x00;
|
||||
public const ushort EV_KEY = 0x01;
|
||||
public const ushort EV_REL = 0x02;
|
||||
public const ushort EV_ABS = 0x03;
|
||||
|
||||
// Key event values
|
||||
public const int KEY_RELEASE = 0;
|
||||
public const int KEY_PRESS = 1;
|
||||
public const int KEY_REPEAT = 2;
|
||||
|
||||
// Linux key codes (from input-event-codes.h)
|
||||
public const ushort KEY_ESC = 1;
|
||||
public const ushort KEY_MINUS = 12;
|
||||
public const ushort KEY_EQUAL = 13;
|
||||
public const ushort KEY_Q = 16;
|
||||
public const ushort KEY_W = 17;
|
||||
public const ushort KEY_E = 18;
|
||||
public const ushort KEY_A = 30;
|
||||
public const ushort KEY_S = 31;
|
||||
public const ushort KEY_D = 32;
|
||||
public const ushort KEY_Z = 44;
|
||||
public const ushort KEY_C = 46;
|
||||
public const ushort KEY_SPACE = 57;
|
||||
public const ushort KEY_KPMINUS = 74;
|
||||
public const ushort KEY_KPPLUS = 78;
|
||||
|
||||
// ioctl constants for evdev
|
||||
// EVIOCGNAME(len): Get device name
|
||||
// Calculated as: _IOC(_IOC_READ, 'E', 0x06, len)
|
||||
// where _IOC_READ=2, 'E'=0x45
|
||||
// Formula: (2<<30) | (0x45<<8) | (0x06) | (256<<16) = 0x80FF4506
|
||||
public const uint EVIOCGNAME_256 = 0x80FF4506;
|
||||
|
||||
// File open flags
|
||||
public const int O_RDONLY = 0x0000;
|
||||
public const int O_NONBLOCK = 0x0800;
|
||||
|
||||
// Error codes
|
||||
public const int EAGAIN = 11;
|
||||
public const int EACCES = 13;
|
||||
|
||||
/// <summary>
|
||||
/// Linux input event structure (24 bytes on 64-bit systems)
|
||||
/// Represents a single input event from evdev
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct input_event
|
||||
{
|
||||
public long tv_sec; // timestamp seconds
|
||||
public long tv_usec; // timestamp microseconds
|
||||
public ushort type; // event type (EV_KEY, EV_REL, etc.)
|
||||
public ushort code; // event code (KEY_W, KEY_A, etc.)
|
||||
public int value; // event value (0=release, 1=press, 2=repeat)
|
||||
}
|
||||
|
||||
// File operations for evdev
|
||||
/// <summary>
|
||||
/// Open a file and return a file descriptor
|
||||
/// </summary>
|
||||
[LibraryImport("libc", SetLastError = true, StringMarshalling = StringMarshalling.Utf8)]
|
||||
public static partial int open(string pathname, int flags);
|
||||
|
||||
/// <summary>
|
||||
/// Close a file descriptor
|
||||
/// </summary>
|
||||
[LibraryImport("libc", SetLastError = true)]
|
||||
public static partial int close(int fd);
|
||||
|
||||
/// <summary>
|
||||
/// Read from a file descriptor into input_event buffer
|
||||
/// </summary>
|
||||
[LibraryImport("libc", SetLastError = true)]
|
||||
public static partial int read(int fd, ref input_event buf, int count);
|
||||
|
||||
/// <summary>
|
||||
/// ioctl system call for device control
|
||||
/// Used to query device name via EVIOCGNAME
|
||||
/// </summary>
|
||||
[LibraryImport("libc", SetLastError = true)]
|
||||
public static partial int ioctl(int fd, uint request, byte[] argp);
|
||||
|
||||
// Error handling
|
||||
/// <summary>
|
||||
/// Get pointer to errno location
|
||||
/// </summary>
|
||||
[LibraryImport("libc")]
|
||||
public static partial IntPtr __errno_location();
|
||||
|
||||
/// <summary>
|
||||
/// Get last error number (errno)
|
||||
/// </summary>
|
||||
public static int GetLastError()
|
||||
{
|
||||
IntPtr errnoPtr = __errno_location();
|
||||
if (errnoPtr == IntPtr.Zero)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return Marshal.ReadInt32(errnoPtr);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user