/* Copyright (c) 1992, 1995 John E. Davis * All rights reserved. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ #include "config.h" #include "sl-feat.h" #include #include #include #include "slang.h" #include "_slang.h" #ifdef __cplusplus # define _DOTS_ ... #else # define _DOTS_ void #endif /*----------------------------------------------------------------------*\ * Function: static void set_ctrl_break (int state); * * set the control-break setting \*----------------------------------------------------------------------*/ static void set_ctrl_break (int state) { } /*----------------------------------------------------------------------*\ * Function: int SLang_init_tty (int abort_char, int no_flow_control, * int opost); * * initialize the keyboard interface and attempt to set-up the interrupt 9 * handler if ABORT_CHAR is non-zero. * NO_FLOW_CONTROL and OPOST are only for compatiblity and are ignored. \*----------------------------------------------------------------------*/ HANDLE hStdout, hStdin; CONSOLE_SCREEN_BUFFER_INFO csbiInfo; int SLang_init_tty (int abort_char, int no_flow_control, int opost) { SMALL_RECT windowRect; COORD newPosition; DWORD flags; /* first off, create a new console so the old one can be restored on exit */ HANDLE console = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ |FILE_SHARE_WRITE, 0, CONSOLE_TEXTMODE_BUFFER, 0); if (SetConsoleActiveScreenBuffer(console) == FALSE) { return -1; } /* start things off at the origin */ newPosition.X = 0; newPosition.Y = 0; /* still read in characters from stdin, but output to the new console */ /* this way, on program exit, the original screen is restored */ hStdin = GetStdHandle(STD_INPUT_HANDLE); /* hStdout = GetStdHandle(STD_OUTPUT_HANDLE); */ /* hStdin = console; */ hStdout = console; if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE) { return -1; /* failure */ } if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { return -1; /* failure */ } // if windowRect.Left = 0; windowRect.Top = 0; windowRect.Right = csbiInfo.dwSize.X - 1; windowRect.Bottom = csbiInfo.dwSize.Y - 1; if (!SetConsoleWindowInfo(hStdout, TRUE, &windowRect)) { return -1; } if (SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT) == FALSE) { return -1; /* failure */ } if (SetConsoleMode(hStdout, 0) == FALSE) { return -1; /* failure */ } if (GetConsoleMode(hStdin, &flags)) { if (flags & ENABLE_PROCESSED_INPUT) { return -1; } } (void) SetConsoleCursorPosition(hStdout, newPosition); /* success */ return 0; } /* SLang_init_tty */ /*----------------------------------------------------------------------*\ * Function: void SLang_reset_tty (void); * * reset the tty before exiting \*----------------------------------------------------------------------*/ void SLang_reset_tty (void) { set_ctrl_break (1); } /* Return TRUE if the Shift, Ctrl, Alt, Caps Lock, or Num Lock key was pressed. */ static int is_shift_key (INPUT_RECORD *pRecord) { unsigned k = (pRecord->Event.KeyEvent.uChar.AsciiChar | (pRecord->Event.KeyEvent.wVirtualScanCode << 8)); return ((k == 0x1d00) || (k == 0x2a00) || (k == 0x3600) || (k == 0x3800) || (k == 0x3a00) || (k == 0x4500)); } /*----------------------------------------------------------------------*\ * Function: int _SLsys_input_pending (int tsecs); * * sleep for *tsecs tenths of a sec waiting for input \*----------------------------------------------------------------------*/ int _SLsys_input_pending (int tsecs) { INPUT_RECORD record; DWORD events_read; while (1) { if (0 == PeekConsoleInput(hStdin, &record, 1, &events_read)) /* function failed */ return 0; if (events_read != 1) return 0; if ((record.EventType == KEY_EVENT) && record.Event.KeyEvent.bKeyDown && (0 == is_shift_key (&record))) /* ok, there is a keypress here */ return 1; /* something else is here, so read it and try again */ (void) ReadConsoleInput(hStdin, &record, 1, &events_read); } } /*----------------------------------------------------------------------*\ * Function: unsigned int _SLsys_getkey (void); * * wait for and get the next available keystroke. * Also re-maps some useful keystrokes. * * Backspace (^H) => Del (127) * Ctrl-Space => ^@ (^@^3 - a pc NUL char) * extended keys are prefixed by a null character \*----------------------------------------------------------------------*/ unsigned int _SLsys_getkey (void) { unsigned int ch; DWORD events_read; INPUT_RECORD record; while (1) { if (!ReadConsoleInput(hStdin, &record, 1, &events_read)) return 0; if ((record.EventType == KEY_EVENT) && record.Event.KeyEvent.bKeyDown && !is_shift_key (&record)) { #ifdef CYGWIN32 ch = record.Event.KeyEvent.AsciiChar; #else ch = record.Event.KeyEvent.uChar.AsciiChar; #endif if (ch == 0 || ch == 0xE0) { SLang_ungetkey(record.Event.KeyEvent.wVirtualScanCode); } return ch; } } /* ReadFile(hStdin, &key, 1, &events_read, NULL); */ /* return key; */ } /*----------------------------------------------------------------------*\ * Function: int SLang_set_abort_signal (void (*handler)(int)); \*----------------------------------------------------------------------*/ int SLang_set_abort_signal (void (*handler)(int)) { return 0; }