_WCRTLINK int kbhit( void ) { DWORD n; HANDLE h; INPUT_RECORD r; #ifdef DEFAULT_WINDOWING if( _WindowsKbhit != 0 ) { LPWDATA res; res = _WindowsIsWindowedHandle( (int) STDIN_FILENO ); return( _WindowsKbhit( res ) ); } #endif _AccessFileH( STDIN_FILENO ); h = __NTConsoleInput(); for(;;) { PeekConsoleInput( h, &r, 1, &n ); if( n == 0 ) break; if( __NTRealKey( &r ) ) break; // flush out mouse, window, and key up events ReadConsoleInput( h, &r, 1, &n ); } // n != 0 if there is a key waiting _ReleaseFileH( STDIN_FILENO ); return( n != 0 ); }
_WCRTLINK char *cgets( char *buff ) { char *p; char len; DWORD n; HANDLE h; INPUT_RECORD r; #ifdef DEFAULT_WINDOWING if( _WindowsStdin != 0 ) { // Default windowing... __qread( STDIN_FILENO, buff + 2, *buff - 1 ); p = buff + 2; len = *buff; for(;;) { if( len <= 1 ) break; if( *p == '\r' || *p == '\0' ) break; ++p; --len; } *p = '\0'; buff[1] = p - buff - 2; return( buff + 2 ); } #endif _AccessFileH( STDIN_FILENO ); h = __NTConsoleInput(); // obtain a console input handle for( p = buff + 2, len = *buff; ; ) { ReadConsoleInput( h, &r, 1, &n ); if( __NTRealKey( &r ) ) { // Only interested in real keys if( r.Event.KeyEvent.uChar.AsciiChar == CRLF ) { *p = '\0'; break; } for( ; r.Event.KeyEvent.wRepeatCount > 0; --r.Event.KeyEvent.wRepeatCount ) { // Deal with backspace first... if( r.Event.KeyEvent.uChar.AsciiChar == BACKSPACE ) { if( p > buff + 2 ) { putch( BACKSPACE ); putch( SPACE ); putch( BACKSPACE ); --p; ++len; } } else if( len > 1 ) { // Other real chars... *p = r.Event.KeyEvent.uChar.AsciiChar; putch( r.Event.KeyEvent.uChar.AsciiChar ); ++p; --len; } // Otherwise: len <= 1, can't type more. } } } _ReleaseFileH( STDIN_FILENO ); buff[1] = p - buff - 2; return( buff + 2 ); }
static int do_getch( HANDLE console_in ) { INPUT_RECORD ir; DWORD n; static unsigned repeat; static int c; static int e; static int state = KS_EMPTY; switch( state ) { case KS_HANDLE_FIRST_CALL: --repeat; if( c != 0 ) { if( repeat == 0 ) { state = KS_EMPTY; } } else { state = KS_HANDLE_SECOND_CALL; } return( c ); case KS_HANDLE_SECOND_CALL: if( repeat == 0 ) { state = KS_EMPTY; } else { state = KS_HANDLE_FIRST_CALL; } return( e ); } for( ;; ) { if( ! ReadConsoleInput( console_in, &ir, 1, &n ) ) break; if( ! __NTRealKey( &ir ) ) continue; repeat = ir.Event.KeyEvent.wRepeatCount - 1; c = (unsigned char)ir.Event.KeyEvent.uChar.AsciiChar; if( (ir.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY) != 0 || c == 0 ) { c = 0; e = ir.Event.KeyEvent.wVirtualScanCode; state = KS_HANDLE_SECOND_CALL; } else { if( repeat != 0 ) { state = KS_HANDLE_FIRST_CALL; } } return( c ); } return( EOF ); }