Beispiel #1
0
//FIXME utf8 input
char *CON_Input( void )
{
	INPUT_RECORD buff[ MAX_EDIT_LINE ];
	DWORD count = 0, events = 0;
	WORD key = 0;
	int i;
	int newlinepos = -1;

	if( !GetNumberOfConsoleInputEvents( qconsole_hin, &events ) )
		return NULL;

	if( events < 1 )
		return NULL;
  
	// if we have overflowed, start dropping oldest input events
	if( events >= MAX_EDIT_LINE )
	{
		ReadConsoleInput( qconsole_hin, buff, 1, &events );
		return NULL;
	} 

	if( !ReadConsoleInput( qconsole_hin, buff, events, &count ) )
		return NULL;

	FlushConsoleInputBuffer( qconsole_hin );

	for( i = 0; i < count; i++ )
	{
		if( buff[ i ].EventType != KEY_EVENT )
			continue;
		if( !buff[ i ].Event.KeyEvent.bKeyDown ) 
			continue;

		key = buff[ i ].Event.KeyEvent.wVirtualKeyCode;

		if( key == VK_RETURN )
		{
			newlinepos = i;
			qconsole_cursor = 0;
			break;
		}
		else if( key == VK_UP )
		{
			CON_HistPrev();
			break;
		}
		else if( key == VK_DOWN )
		{
			CON_HistNext();
			break;
		}
		else if( key == VK_LEFT )
		{
			qconsole_cursor--;
			if ( qconsole_cursor < 0 )
			{
				qconsole_cursor = 0;
			}
			break;
		}
		else if( key == VK_RIGHT )
		{
			qconsole_cursor++;
			if ( qconsole_cursor > qconsole_linelen )
			{
				qconsole_cursor = qconsole_linelen;
			}
			break;
		}
		else if( key == VK_HOME )
		{
			qconsole_cursor = 0;
			break;
		}
		else if( key == VK_END )
		{
			qconsole_cursor = qconsole_linelen;
			break;
		}
		else if( key == VK_TAB )
		{
			field_t f;
			const char *fieldString;

			//Q_strncpyz( f.buffer, qconsole_line, sizeof( f.buffer ) );
			Field_SetBuffer(&f, qconsole_line, sizeof(qconsole_line), 0);
			Field_AutoComplete( &f );
			//Q_strncpyz( qconsole_line, f.buffer, sizeof( qconsole_line ) );
			fieldString = Field_AsStr(&f, 0, 0);
			Q_strncpyz(qconsole_line, fieldString, sizeof(qconsole_line));

			qconsole_linelen = strlen( qconsole_line );
			qconsole_cursor = qconsole_linelen;
			break;
		}

		if( qconsole_linelen < sizeof( qconsole_line ) - 1 )
		{
			char c = buff[ i ].Event.KeyEvent.uChar.AsciiChar;

			if( key == VK_BACK )
			{
				if ( qconsole_cursor > 0 )
				{
					int newlen = ( qconsole_linelen > 0 ) ? qconsole_linelen - 1 : 0;
					if ( qconsole_cursor < qconsole_linelen )
					{
						memmove( qconsole_line + qconsole_cursor - 1,
								 qconsole_line + qconsole_cursor,
								 qconsole_linelen - qconsole_cursor );
					}

					qconsole_line[ newlen ] = '\0';
					qconsole_linelen = newlen;
					qconsole_cursor--;
				}
			}
			else if( c )
			{
				if ( qconsole_linelen > qconsole_cursor )
				{
					memmove( qconsole_line + qconsole_cursor + 1,
							 qconsole_line + qconsole_cursor,
							 qconsole_linelen - qconsole_cursor );
				}

				qconsole_line[ qconsole_cursor++ ] = c;

				qconsole_linelen++;
				qconsole_line[ qconsole_linelen ] = '\0'; 
			}
		}
	}

	if( newlinepos < 0) {
		CON_Show();
		return NULL;
	}

	if( !qconsole_linelen )
	{
		CON_Show();
		Com_Printf( "\n" );
		return NULL;
	}

	qconsole_linelen = 0;
	CON_Show();

	CON_HistAdd();
	Com_Printf( "%s\n", qconsole_line );

	return qconsole_line;
}
Beispiel #2
0
/*
==================
CON_Input
==================
*/
char *CON_Input( void )
{
	// we use this when sending back commands
	static char text[MAX_EDIT_LINE];
	int avail;
	char key;
	field_t *history;
	size_t UNUSED_VAR size;

	if(ttycon_on)
	{
		//FIXME utf8
		avail = read(STDIN_FILENO, &key, 1);
		if (avail != -1)
		{
			// we have something
			// backspace?
			// NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
			if ((key == TTY_erase) || (key == 127) || (key == 8))
			{
				if (TTY_con.cursor > 0)
				{
					TTY_con.cursor--;
					//TTY_con.buffer[TTY_con.cursor] = '\0';
					TTY_con.xbuffer[TTY_con.cursor].codePoint = '\0';
					TTY_con.xbuffer[TTY_con.cursor].numUtf8Bytes = 1;
					TTY_con.xbuffer[TTY_con.cursor].utf8Bytes[0] = '\0';
					CON_Back();
				}
				return NULL;
			}
			// check if this is a control char
			if ((key) && (key) < ' ')
			{
				if (key == '\n')
				{
					const char *fieldString;

					// push it in history
					Hist_Add(&TTY_con);
					//Q_strncpyz(text, TTY_con.buffer, sizeof(text));
					fieldString = Field_AsStr(&TTY_con, 0, 0);
					Q_strncpyz(text, fieldString, sizeof(text));
					Field_Clear(&TTY_con);
					key = '\n';
					size = write(STDOUT_FILENO, &key, 1);
					size = write(STDOUT_FILENO, "]", 1);
					return text;
				}
				if (key == '\t')
				{
					CON_Hide();
					Field_AutoComplete( &TTY_con );
					CON_Show();
					return NULL;
				}
				avail = read(STDIN_FILENO, &key, 1);
				if (avail != -1)
				{
					// VT 100 keys
					if (key == '[' || key == 'O')
					{
						avail = read(STDIN_FILENO, &key, 1);
						if (avail != -1)
						{
							switch (key)
							{
								case 'A':
									history = Hist_Prev();
									if (history)
									{
										CON_Hide();
										TTY_con = *history;
										CON_Show();
									}
									CON_FlushIn();
									return NULL;
									break;
								case 'B':
									history = Hist_Next();
									CON_Hide();
									if (history)
									{
										TTY_con = *history;
									} else
									{
										Field_Clear(&TTY_con);
									}
									CON_Show();
									CON_FlushIn();
									return NULL;
									break;
								case 'C':
									return NULL;
								case 'D':
									return NULL;
							}
						}
					}
				}
				Com_DPrintf("droping ISCTL sequence: %d, TTY_erase: %d\n", key, TTY_erase);
				CON_FlushIn();
				return NULL;
			}
			if (TTY_con.cursor >= sizeof(text) - 1)
				return NULL;

			//FIXME utf8
			// push regular character
			//TTY_con.buffer[TTY_con.cursor] = key;
			TTY_con.xbuffer[TTY_con.cursor].codePoint = key;
			TTY_con.xbuffer[TTY_con.cursor].utf8Bytes[0] = key;
			TTY_con.xbuffer[TTY_con.cursor].numUtf8Bytes = 0;

			TTY_con.cursor++;
			// print the current line (this is differential)
			size = write(STDOUT_FILENO, &key, 1);
		}

		return NULL;
	}
	else if (stdin_active)
	{
		int     len;
		fd_set  fdset;
		struct timeval timeout;

		FD_ZERO(&fdset);
		FD_SET(STDIN_FILENO, &fdset); // stdin
		timeout.tv_sec = 0;
		timeout.tv_usec = 0;
		if(select (STDIN_FILENO + 1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(STDIN_FILENO, &fdset))
			return NULL;

		len = read(STDIN_FILENO, text, sizeof(text));
		if (len == 0)
		{ // eof!
			stdin_active = qfalse;
			return NULL;
		}

		if (len < 1)
			return NULL;
		text[len-1] = 0;    // rip off the /n and terminate

		return text;
	}
	return NULL;
}