char *CTextConsoleWin32::GetLine() { while (true) { INPUT_RECORD recs[1024]; unsigned long numread; unsigned long numevents; if (!GetNumberOfConsoleInputEvents(hinput, &numevents)) { if (m_System) { m_System->Errorf("CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents\n"); } return nullptr; } if (numevents <= 0) break; if (!ReadConsoleInput(hinput, recs, ARRAYSIZE(recs), &numread)) { if (m_System) { m_System->Errorf("CTextConsoleWin32::GetLine: !ReadConsoleInput\n"); } return nullptr; } if (numread == 0) return nullptr; for (int i = 0; i < (int)numread; i++) { INPUT_RECORD *pRec = &recs[i]; if (pRec->EventType != KEY_EVENT) continue; if (pRec->Event.KeyEvent.bKeyDown) { // check for cursor keys if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_UP) { ReceiveUpArrow(); } else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_DOWN) { ReceiveDownArrow(); } else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_LEFT) { ReceiveLeftArrow(); } else if (pRec->Event.KeyEvent.wVirtualKeyCode == VK_RIGHT) { ReceiveRightArrow(); } else { int nLen; char ch = pRec->Event.KeyEvent.uChar.AsciiChar; switch (ch) { case '\r': // Enter nLen = ReceiveNewline(); if (nLen) { return m_szConsoleText; } break; case '\b': // Backspace ReceiveBackspace(); break; case '\t': // TAB ReceiveTab(); break; default: // dont' accept nonprintable chars if ((ch >= ' ') && (ch <= '~')) { ReceiveStandardChar(ch); } break; } } } } } return nullptr; }
char * CTextConsoleUnix::GetLine( void ) { if ( !kbhit() ) // early return for 99.999% case :) return NULL; escape_sequence_t es; es = ESCAPE_CLEAR; sigset_t block_ttou; sigemptyset (&block_ttou); sigaddset (&block_ttou, SIGTTOU); sigaddset (&block_ttou, SIGTTIN); sigprocmask (SIG_BLOCK, &block_ttou, NULL); while ( 1 ) { char ch; int nLen; if ( !kbhit() ) break; ch = 0; int numRead = read( STDIN_FILENO, &ch, 1 ); if ( !numRead ) break; switch (ch) { case '\n': // Enter es = ESCAPE_CLEAR; nLen = ReceiveNewline(); if ( nLen ) { sigprocmask (SIG_UNBLOCK, &block_ttou, NULL); return m_szConsoleText; } break; case 127: // Backspace case '\b': // Backspace es = ESCAPE_CLEAR; ReceiveBackspace(); break; case '\t': // TAB es = ESCAPE_CLEAR; ReceiveTab(); break; case 27: // Escape character es = ESCAPE_RECEIVED; break; case '[': // 2nd part of escape sequence case 'O': case 'o': switch( es ) { case ESCAPE_CLEAR: case ESCAPE_BRACKET_RECEIVED: es = ESCAPE_CLEAR; ReceiveStandardChar( ch ); break; case ESCAPE_RECEIVED: es = ESCAPE_BRACKET_RECEIVED; break; } break; case 'A': if ( es == ESCAPE_BRACKET_RECEIVED ) { es = ESCAPE_CLEAR; ReceiveUpArrow(); } else { es = ESCAPE_CLEAR; ReceiveStandardChar( ch ); } break; case 'B': if ( es == ESCAPE_BRACKET_RECEIVED ) { es = ESCAPE_CLEAR; ReceiveDownArrow(); } else { es = ESCAPE_CLEAR; ReceiveStandardChar( ch ); } break; case 'C': if ( es == ESCAPE_BRACKET_RECEIVED ) { es = ESCAPE_CLEAR; ReceiveRightArrow(); } else { es = ESCAPE_CLEAR; ReceiveStandardChar( ch ); } break; case 'D': if ( es == ESCAPE_BRACKET_RECEIVED ) { es = ESCAPE_CLEAR; ReceiveLeftArrow(); } else { es = ESCAPE_CLEAR; ReceiveStandardChar( ch ); } break; default: if ( es != ESCAPE_BRACKET_RECEIVED ) // Just eat this char if it's an unsupported escape { if ( ( ch >= ' ') && ( ch <= '~' ) ) // dont' accept nonprintable chars { es = ESCAPE_CLEAR; ReceiveStandardChar( ch ); } } break; } fflush( stdout ); } sigprocmask (SIG_UNBLOCK, &block_ttou, NULL); return NULL; }