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;
}