const string lib = "libc";
[DllImport(lib)]
+ public static extern int dup(int file);
+
+ [DllImport(lib)]
+ public static extern int dup2(int file1, int file2);
+
+ [DllImport(lib)]
public static extern int ioctl(int d, JoystickIoctlCode request, ref int data);
[DllImport(lib)]
{
const string lib = "libc";
+ [DllImport(lib, EntryPoint = "isatty", CallingConvention = CallingConvention.Cdecl)]
+ [return: MarshalAs(UnmanagedType.I4)]
+ public static extern bool IsTerminal(int fd);
+
[DllImport(lib, EntryPoint = "tcgetattr", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetAttributes(int fd, out TerminalState state);
TerminalState current_state;
IntPtr original_mode = new IntPtr(-1);
+ int original_stdin;
public LinuxKeyboardTTY()
{
+ Debug.Print("[Linux] Using TTY keyboard input.");
+
if (!SetupTTY(stdin))
{
throw new NotSupportedException();
bool SetupTTY(int stdin)
{
+ // Ensure that we are using a real terminal,
+ // rather than some short of file redirection.thing.
+ if (!Terminal.IsTerminal(stdin))
+ {
+ Debug.Print("[Linux] Terminal.IsTerminal({0}) returned false.", stdin);
+ return false;
+ }
+
+ //original_stdin = Libc.dup(stdin);
+
int ret = Terminal.GetAttributes(stdin, out original_state);
if (ret < 0)
{
// Update terminal state
current_state = original_state;
- current_state.LocalMode &= ~(LocalFlags.ECHO | LocalFlags.ICANON | LocalFlags.ISIG);
+ current_state.LocalMode &= ~(/*LocalFlags.ECHO |*/ LocalFlags.ICANON | LocalFlags.ISIG);
current_state.InputMode &= ~(
InputFlags.ISTRIP | InputFlags.IGNCR | InputFlags.ICRNL |
InputFlags.INLCR | InputFlags.IXOFF | InputFlags.IXON);
{
if (original_mode != new IntPtr(-1))
{
+ Debug.Print("[Linux] Exiting TTY keyboard input.");
+
Libc.ioctl(stdin, KeyboardIoctlCode.SetMode, ref original_mode);
Terminal.SetAttributes(stdin, OptionalActions.FLUSH, ref original_state);
original_mode = new IntPtr(-1);