Beispiel #1
0
/*
====================
GetClipboardData
====================
*/
static void GetClipboardData( char *buf, int buflen ) {
	char	*cbd;

	cbd = Sys_GetClipboardData();

	if ( !cbd ) {
		*buf = 0;
		return;
	}

	Q_strncpyz( buf, cbd, buflen );

	Z_Free( cbd );
}
Beispiel #2
0
/*
====================
GetClipboardData
====================
*/
static void GetClipboardData( char *buf, int buflen ) {
	char	*cbd, *c;

	c = cbd = Sys_GetClipboardData();
	if ( !cbd ) {
		*buf = 0;
		return;
	}

	for ( int i = 0, end = buflen - 1; *c && i < end; i++ )
	{
		uint32_t utf32 = ConvertUTF8ToUTF32( c, &c );
		buf[i] = ConvertUTF32ToExpectedCharset( utf32 );
	}

	Z_Free( cbd );
}
Beispiel #3
0
static void PasteToConsole (void)
{
	char *cbd, *p, *workline;
	int mvlen, inslen;

	if (key_linepos == MAXCMDLINE - 1)
		return;

	if ((cbd = Sys_GetClipboardData()) == NULL)
		return;

	p = cbd;
	while (*p)
	{
		if (*p == '\n' || *p == '\r' || *p == '\b')
		{
			*p = 0;
			break;
		}
		p++;
	}

	inslen = (int) (p - cbd);
	if (inslen + key_linepos > MAXCMDLINE - 1)
		inslen = MAXCMDLINE - 1 - key_linepos;
	if (inslen <= 0) goto done;

	workline = key_lines[edit_line];
	workline += key_linepos;
	mvlen = (int) strlen(workline);
	if (mvlen + inslen + key_linepos > MAXCMDLINE - 1)
	{
		mvlen = MAXCMDLINE - 1 - key_linepos - inslen;
		if (mvlen < 0) mvlen = 0;
	}

	// insert the string
	if (mvlen != 0)
		memmove (workline + inslen, workline, mvlen);
	memcpy (workline, cbd, inslen);
	key_linepos += inslen;
	workline[mvlen + inslen] = '\0';
  done:
	Z_Free(cbd);
}
Beispiel #4
0
/*
================
Field_Paste
================
*/
void Field_Paste( field_t *edit ) {
	char	*cbd;
	int		pasteLen, i;

	cbd = Sys_GetClipboardData();

	if ( !cbd ) {
		return;
	}

	// send as if typed, so insert / overstrike works properly
	pasteLen = strlen( cbd );
	for ( i = 0 ; i < pasteLen ; i++ ) {
		Field_CharEvent( edit, cbd[i] );
	}

	Z_Free( cbd );
}
Beispiel #5
0
/*
===============
idEditField::Paste
===============
*/
void idEditField::Paste( void )
{
	char	*cbd;
	int		pasteLen, i;
	
	cbd = Sys_GetClipboardData();
	
	if( !cbd )
	{
		return;
	}
	
	// send as if typed, so insert / overstrike works properly
	pasteLen = strlen( cbd );
	
	for( i = 0; i < pasteLen; i++ )
	{
		CharEvent( cbd[i] );
	}
	
	Mem_Free( cbd );
}
Beispiel #6
0
Datei: qmenu.c Projekt: ZwS/qudos
qboolean
Field_Key(menufield_s * f, int key)
{
	extern int	keydown[];

	switch (key) {
	case K_KP_SLASH:
		key = '/';
		break;
	case K_KP_MINUS:
		key = '-';
		break;
	case K_KP_PLUS:
		key = '+';
		break;
	case K_KP_HOME:
		key = '7';
		break;
	case K_KP_UPARROW:
		key = '8';
		break;
	case K_KP_PGUP:
		key = '9';
		break;
	case K_KP_LEFTARROW:
		key = '4';
		break;
	case K_KP_5:
		key = '5';
		break;
	case K_KP_RIGHTARROW:
		key = '6';
		break;
	case K_KP_END:
		key = '1';
		break;
	case K_KP_DOWNARROW:
		key = '2';
		break;
	case K_KP_PGDN:
		key = '3';
		break;
	case K_KP_INS:
		key = '0';
		break;
	case K_KP_DEL:
		key = '.';
		break;
	}

	if (key > 127) {
		switch (key) {
		case K_DEL:
		default:
			return false;
		}
	}

	/*
	 * * support pasting from the clipboard
	 */
	if ((toupper(key) == 'V' && keydown[K_CTRL]) ||
	    (((key == K_INS) || (key == K_KP_INS)) && keydown[K_SHIFT])) {
		char           *cbd;

		if ((cbd = Sys_GetClipboardData()) != 0) {
			strtok(cbd, "\n\r\b");

			Q_strncpyz(f->buffer, cbd, f->length);
			f->cursor = strlen(f->buffer);
			f->visible_offset = f->cursor - f->visible_length;
			if (f->visible_offset < 0)
				f->visible_offset = 0;

			free(cbd);
		}
		return true;
	}
	switch (key) {
	case K_KP_LEFTARROW:
	case K_LEFTARROW:
	case K_BACKSPACE:
		if (f->cursor > 0) {
			memmove(&f->buffer[f->cursor - 1], &f->buffer[f->cursor], strlen(&f->buffer[f->cursor]) + 1);
			f->cursor--;

			if (f->visible_offset) {
				f->visible_offset--;
			}
		}
		break;

	case K_KP_DEL:
	case K_DEL:
		memmove(&f->buffer[f->cursor], &f->buffer[f->cursor + 1], strlen(&f->buffer[f->cursor + 1]) + 1);
		break;

	case K_KP_ENTER:
	case K_ENTER:
	case K_ESCAPE:
	case K_TAB:
		return false;

	case K_SPACE:
	default:
		if (!isdigit(key) && (f->generic.flags & QMF_NUMBERSONLY))
			return false;

		if (f->cursor < f->length) {
			f->buffer[f->cursor++] = key;
			f->buffer[f->cursor] = 0;

			if (f->cursor > f->visible_length) {
				f->visible_offset++;
			}
		}
	}

	return true;
}
Beispiel #7
0
/*
====================
Interactive line editing and console scrollback
====================
*/
static void
Key_Console (int key, int unicode)
{
	// LordHavoc: copied most of this from Q2 to improve keyboard handling
	switch (key)
	{
	case K_KP_SLASH:
		key = '/';
		break;
	case K_KP_MINUS:
		key = '-';
		break;
	case K_KP_PLUS:
		key = '+';
		break;
	case K_KP_HOME:
		key = '7';
		break;
	case K_KP_UPARROW:
		key = '8';
		break;
	case K_KP_PGUP:
		key = '9';
		break;
	case K_KP_LEFTARROW:
		key = '4';
		break;
	case K_KP_5:
		key = '5';
		break;
	case K_KP_RIGHTARROW:
		key = '6';
		break;
	case K_KP_END:
		key = '1';
		break;
	case K_KP_DOWNARROW:
		key = '2';
		break;
	case K_KP_PGDN:
		key = '3';
		break;
	case K_KP_INS:
		key = '0';
		break;
	case K_KP_DEL:
		key = '.';
		break;
	}

	if ((key == 'v' && keydown[K_CTRL]) || ((key == K_INS || key == K_KP_INS) && keydown[K_SHIFT]))
	{
		char *cbd, *p;
		if ((cbd = Sys_GetClipboardData()) != 0)
		{
			int i;
#if 1
			p = cbd;
			while (*p)
			{
				if (*p == '\r' && *(p+1) == '\n')
				{
					*p++ = ';';
					*p++ = ' ';
				}
				else if (*p == '\n' || *p == '\r' || *p == '\b')
					*p++ = ';';
				p++;
			}
#else
			strtok(cbd, "\n\r\b");
#endif
			i = (int)strlen(cbd);
			if (i + key_linepos >= MAX_INPUTLINE)
				i= MAX_INPUTLINE - key_linepos - 1;
			if (i > 0)
			{
				// terencehill: insert the clipboard text between the characters of the line
				/*
				char *temp = (char *) Z_Malloc(MAX_INPUTLINE);
				cbd[i]=0;
				temp[0]=0;
				if ( key_linepos < (int)strlen(key_line) )
					strlcpy(temp, key_line + key_linepos, (int)strlen(key_line) - key_linepos +1);
				key_line[key_linepos] = 0;
				strlcat(key_line, cbd, sizeof(key_line));
				if (temp[0])
					strlcat(key_line, temp, sizeof(key_line));
				Z_Free(temp);
				key_linepos += i;
				*/
				// blub: I'm changing this to use memmove() like the rest of the code does.
				cbd[i] = 0;
				memmove(key_line + key_linepos + i, key_line + key_linepos, sizeof(key_line) - key_linepos - i);
				memcpy(key_line + key_linepos, cbd, i);
				key_linepos += i;
			}
			Z_Free(cbd);
		}
		return;
	}

	if (key == 'l' && keydown[K_CTRL])
	{
		Cbuf_AddText ("clear\n");
		return;
	}

	if (key == 'u' && keydown[K_CTRL]) // like vi/readline ^u: delete currently edited line
	{
		// clear line
		key_line[0] = ']';
		key_line[1] = 0;
		key_linepos = 1;
		return;
	}

	if (key == 'q' && keydown[K_CTRL]) // like zsh ^q: push line to history, don't execute, and clear
	{
		// clear line
		Key_History_Push();
		key_line[0] = ']';
		key_line[1] = 0;
		key_linepos = 1;
		return;
	}

	if (key == K_ENTER || key == K_KP_ENTER)
	{
		Cbuf_AddText (key_line+1);	// skip the ]
		Cbuf_AddText ("\n");
		Key_History_Push();
		key_line[0] = ']';
		key_line[1] = 0;	// EvilTypeGuy: null terminate
		key_linepos = 1;
		// force an update, because the command may take some time
		if (cls.state == ca_disconnected)
			CL_UpdateScreen ();
		return;
	}

	if (key == K_TAB)
	{
		if(keydown[K_CTRL]) // append to the cvar its value
		{
			int		cvar_len, cvar_str_len, chars_to_move;
			char	k;
			char	cvar[MAX_INPUTLINE];
			const char *cvar_str;
			
			// go to the start of the variable
			while(--key_linepos)
			{
				k = key_line[key_linepos];
				if(k == '\"' || k == ';' || k == ' ' || k == '\'')
					break;
			}
			key_linepos++;
			
			// save the variable name in cvar
			for(cvar_len=0; (k = key_line[key_linepos + cvar_len]) != 0; cvar_len++)
			{
				if(k == '\"' || k == ';' || k == ' ' || k == '\'')
					break;
				cvar[cvar_len] = k;
			}
			if (cvar_len==0)
				return;
			cvar[cvar_len] = 0;
			
			// go to the end of the cvar
			key_linepos += cvar_len;
			
			// save the content of the variable in cvar_str
			cvar_str = Cvar_VariableString(cvar);
			cvar_str_len = strlen(cvar_str);
			if (cvar_str_len==0)
				return;
			
			// insert space and cvar_str in key_line
			chars_to_move = strlen(&key_line[key_linepos]);
			if (key_linepos + 1 + cvar_str_len + chars_to_move < MAX_INPUTLINE)
			{
				if (chars_to_move)
					memmove(&key_line[key_linepos + 1 + cvar_str_len], &key_line[key_linepos], chars_to_move);
				key_line[key_linepos++] = ' ';
				memcpy(&key_line[key_linepos], cvar_str, cvar_str_len);
				key_linepos += cvar_str_len;
				key_line[key_linepos + chars_to_move] = 0;
			}
			else
				Con_Printf("Couldn't append cvar value, edit line too long.\n");
			return;
		}
		// Enhanced command completion
		// by EvilTypeGuy [email protected]
		// Thanks to Fett, Taniwha
		Con_CompleteCommandLine();
		return;
	}

	// Advanced Console Editing by Radix [email protected]
	// Added/Modified by EvilTypeGuy [email protected]
	// Enhanced by [515]
	// Enhanced by terencehill

	// move cursor to the previous character
	if (key == K_LEFTARROW || key == K_KP_LEFTARROW)
	{
		if (key_linepos < 2)
			return;
		if(keydown[K_CTRL]) // move cursor to the previous word
		{
			int		pos;
			char	k;
			pos = key_linepos-1;

			if(pos) // skip all "; ' after the word
				while(--pos)
				{
					k = key_line[pos];
					if (!(k == '\"' || k == ';' || k == ' ' || k == '\''))
						break;
				}

			if(pos)
				while(--pos)
				{
					k = key_line[pos];
					if(k == '\"' || k == ';' || k == ' ' || k == '\'')
						break;
				}
			key_linepos = pos + 1;
		}
		else if(keydown[K_SHIFT]) // move cursor to the previous character ignoring colors
		{
			int		pos;
			size_t          inchar = 0;
			pos = u8_prevbyte(key_line, key_linepos);
			while (pos)
				if(pos-1 > 0 && key_line[pos-1] == STRING_COLOR_TAG && isdigit(key_line[pos]))
					pos-=2;
				else if(pos-4 > 0 && key_line[pos-4] == STRING_COLOR_TAG && key_line[pos-3] == STRING_COLOR_RGB_TAG_CHAR
						&& isxdigit(key_line[pos-2]) && isxdigit(key_line[pos-1]) && isxdigit(key_line[pos]))
					pos-=5;
				else
				{
					if(pos-1 > 0 && key_line[pos-1] == STRING_COLOR_TAG && key_line[pos] == STRING_COLOR_TAG) // consider ^^ as a character
						pos--;
					pos--;
					break;
				}
			// we need to move to the beginning of the character when in a wide character:
			u8_charidx(key_line, pos + 1, &inchar);
			key_linepos = pos + 1 - inchar;
		}
		else
		{
			key_linepos = u8_prevbyte(key_line, key_linepos);
		}
		return;
	}

	// delete char before cursor
	if (key == K_BACKSPACE || (key == 'h' && keydown[K_CTRL]))
	{
		if (key_linepos > 1)
		{
			int newpos = u8_prevbyte(key_line, key_linepos);
			strlcpy(key_line + newpos, key_line + key_linepos, sizeof(key_line) + 1 - key_linepos);
			key_linepos = newpos;
		}
		return;
	}

	// delete char on cursor
	if (key == K_DEL || key == K_KP_DEL)
	{
		size_t linelen;
		linelen = strlen(key_line);
		if (key_linepos < (int)linelen)
			memmove(key_line + key_linepos, key_line + key_linepos + u8_bytelen(key_line + key_linepos, 1), linelen - key_linepos);
		return;
	}


	// move cursor to the next character
	if (key == K_RIGHTARROW || key == K_KP_RIGHTARROW)
	{
		if (key_linepos >= (int)strlen(key_line))
			return;
		if(keydown[K_CTRL]) // move cursor to the next word
		{
			int		pos, len;
			char	k;
			len = (int)strlen(key_line);
			pos = key_linepos;

			while(++pos < len)
			{
				k = key_line[pos];
				if(k == '\"' || k == ';' || k == ' ' || k == '\'')
					break;
			}
			
			if (pos < len) // skip all "; ' after the word
				while(++pos < len)
				{
					k = key_line[pos];
					if (!(k == '\"' || k == ';' || k == ' ' || k == '\''))
						break;
				}
			key_linepos = pos;
		}
		else if(keydown[K_SHIFT]) // move cursor to the next character ignoring colors
		{
			int		pos, len;
			len = (int)strlen(key_line);
			pos = key_linepos;
			
			// go beyond all initial consecutive color tags, if any
			if(pos < len)
				while (key_line[pos] == STRING_COLOR_TAG)
				{
					if(isdigit(key_line[pos+1]))
						pos+=2;
					else if(key_line[pos+1] == STRING_COLOR_RGB_TAG_CHAR && isxdigit(key_line[pos+2]) && isxdigit(key_line[pos+3]) && isxdigit(key_line[pos+4]))
						pos+=5;
					else
						break;
				}
			
			// skip the char
			if (key_line[pos] == STRING_COLOR_TAG && key_line[pos+1] == STRING_COLOR_TAG) // consider ^^ as a character
				pos++;
			pos += u8_bytelen(key_line + pos, 1);
			
			// now go beyond all next consecutive color tags, if any
			if(pos < len)
				while (key_line[pos] == STRING_COLOR_TAG)
				{
					if(isdigit(key_line[pos+1]))
						pos+=2;
					else if(key_line[pos+1] == STRING_COLOR_RGB_TAG_CHAR && isxdigit(key_line[pos+2]) && isxdigit(key_line[pos+3]) && isxdigit(key_line[pos+4]))
						pos+=5;
					else
						break;
				}
			key_linepos = pos;
		}
		else
			key_linepos += u8_bytelen(key_line + key_linepos, 1);
		return;
	}

	if (key == K_INS || key == K_KP_INS) // toggle insert mode
	{
		key_insert ^= 1;
		return;
	}

	// End Advanced Console Editing

	if (key == K_UPARROW || key == K_KP_UPARROW || (key == 'p' && keydown[K_CTRL]))
	{
		Key_History_Up();
		return;
	}

	if (key == K_DOWNARROW || key == K_KP_DOWNARROW || (key == 'n' && keydown[K_CTRL]))
	{
		Key_History_Down();
		return;
	}
	// ~1.0795 = 82/76  using con_textsize 64 76 is height of the char, 6 is the distance between 2 lines
	if (key == K_PGUP || key == K_KP_PGUP)
	{
		if(keydown[K_CTRL])
		{
			con_backscroll += ((vid_conheight.integer >> 2) / con_textsize.integer)-1;
		}
		else
			con_backscroll += ((vid_conheight.integer >> 1) / con_textsize.integer)-3;
		return;
	}
Beispiel #8
0
/*
====================
Key_Console

Interactive line editing and console scrollback
====================
*/
void Key_Console (int key)
{

	switch ( key )
	{
	case K_KP_SLASH:
		key = '/';
		break;
	case K_KP_MINUS:
		key = '-';
		break;
	case K_KP_PLUS:
		key = '+';
		break;
	case K_KP_HOME:
		key = '7';
		break;
	case K_KP_UPARROW:
		key = '8';
		break;
	case K_KP_PGUP:
		key = '9';
		break;
	case K_KP_LEFTARROW:
		key = '4';
		break;
	case K_KP_5:
		key = '5';
		break;
	case K_KP_RIGHTARROW:
		key = '6';
		break;
	case K_KP_END:
		key = '1';
		break;
	case K_KP_DOWNARROW:
		key = '2';
		break;
	case K_KP_PGDN:
		key = '3';
		break;
	case K_KP_INS:
		key = '0';
		break;
	case K_KP_DEL:
		key = '.';
		break;
	}

	if ( ( toupper( key ) == 'V' && keydown[K_CTRL] ) ||
		 ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && keydown[K_SHIFT] ) )
	{
		char *cbd;
		
		if ( ( cbd = Sys_GetClipboardData() ) != 0 )
		{
			int		i;
			char	*p, *s;

			p = cbd;
			while ((p = strchr (p, '\r')) != NULL)
				p[0] = ' ';

			//r1: multiline paste
			p = strrchr (cbd, '\n');
			if (p)
			{
				s = strrchr (p, '\n');
				if (s)
				{
					s[0] = 0;
					p++;
					if (cbd[0])
					{
						Cbuf_AddText (cbd);
						Cbuf_AddText ("\n");
						Com_Printf ("%s\n", LOG_GENERAL, cbd);
					}
				}
			}
			else
				p = cbd;
			
			i = (int)strlen( p );

			//r1: save byte for null terminator!!
			if ( i + key_linepos >= MAXCMDLINE - 1)
				i = MAXCMDLINE - key_linepos - 1;

			if ( i > 0 )
			{
				p[i]=0;
				strcat( key_lines[edit_line], p );
				key_linepos += i;
			}
			free( cbd );
		}

		return;
	}

	if ( key == 'l' ) 
	{
		if ( keydown[K_CTRL] )
		{
			Cbuf_AddText ("clear\n");
			return;
		}
	}

	if ( key == K_ENTER || key == K_KP_ENTER )
	{	// backslash text are commands, else chat
		if (key_lines[edit_line][1] == '\\' || key_lines[edit_line][1] == '/')
			Cbuf_AddText (key_lines[edit_line]+2);	// skip the >
		else
			Cbuf_AddText (key_lines[edit_line]+1);	// valid command

		Cbuf_AddText ("\n");
		Com_Printf ("%s\n", LOG_CLIENT,key_lines[edit_line]);
		edit_line = (edit_line + 1) & 31;
		history_line = edit_line;
		memset (key_lines[edit_line], 0, sizeof(key_lines[edit_line]));
		key_lines[edit_line][0] = ']';
		//key_lines[edit_line][1] = '\0';
		key_linepos = 1;
		if (cls.state == ca_disconnected)
			SCR_UpdateScreen ();	// force an update, because the command
									// may take some time
		return;
	}

	//r1: command completion stolen from proquake
	if (key == K_TAB)
	{	// command completion
		if (cl_cmdcomplete->intvalue == 1)
		{
			const char *cmd;
			int len, i;
			char *fragment;
			cvar_t *var;
			const char *best = "~";
			const char *least = "~";

			len = (int)strlen(key_lines[edit_line]);
			for (i = 0 ; i < len - 1 ; i++)
			{
				if (key_lines[edit_line][i] == ' ')
					return;
			}
			fragment = key_lines[edit_line] + 1;

			len--;
			for (var = cvar_vars->next ; var ; var = var->next)
			{
				if (strcmp(var->name, fragment) >= 0 && strcmp(best, var->name) > 0)
					best = var->name;
				if (strcmp(var->name, least) < 0)
					least = var->name;
			}
			cmd = Cmd_CompleteCommand(fragment);
			//if (strcmp(cmd, fragment) >= 0 && strcmp(best, cmd) > 0)
			if (cmd)
				best = cmd;
			if (best[0] == '~')
			{
				cmd = Cmd_CompleteCommand(" ");
				if (strcmp(cmd, least) < 0)
					best = cmd;
				else
					best = least;
			}

			//r1: maybe completing cvar/cmd from net?
			snprintf(key_lines[edit_line], sizeof(key_lines[edit_line])-1, "]%s ", best);
			key_lines[edit_line][sizeof(key_lines[edit_line])-1] = 0;

			key_linepos = (int)strlen(key_lines[edit_line]);
		}
		else if (cl_cmdcomplete->value == 2)
		{
			Key_CompleteCommand();
		}
		else
		{
			Key_CompleteCommandOld();
		}
		return;
	}

	if ( key == K_LEFTARROW )
	{
		if (key_linepos > 1)
			key_linepos--;
		return;
	}

	if (key == K_RIGHTARROW)
	{
		if (key_lines[edit_line][key_linepos])
			key_linepos++;
		return;
	}
	
	if ( ( key == K_BACKSPACE ) || ( ( key == 'h' ) && ( keydown[K_CTRL] ) ) )
	{
		if (key_linepos > 1)
		{
			memmove (key_lines[edit_line] + key_linepos-1, key_lines[edit_line] + key_linepos, sizeof(key_lines[edit_line])-key_linepos);
			key_linepos--;
		}
		return;
	}

	if ( key == K_DEL )
	{
		memmove (key_lines[edit_line] + key_linepos, key_lines[edit_line] + key_linepos + 1, sizeof(key_lines[edit_line])-key_linepos-1);
		return;
	}

	if ( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) ||
		 ( ( key == 'p' ) && keydown[K_CTRL] ) )
	{
		do
		{
			history_line = (history_line - 1) & 31;
		} while (history_line != edit_line
				&& !key_lines[history_line][1]);
		if (history_line == edit_line)
			history_line = (edit_line+1)&31;
		strcpy(key_lines[edit_line], key_lines[history_line]);
		key_linepos = (int)strlen(key_lines[edit_line]);
		return;
	}

	if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) ||
		 ( ( key == 'n' ) && keydown[K_CTRL] ) )
	{
		if (history_line == edit_line) return;
		do
		{
			history_line = (history_line + 1) & 31;
		}
		while (history_line != edit_line
			&& !key_lines[history_line][1]);
		if (history_line == edit_line)
		{
			key_lines[edit_line][0] = ']';
			key_lines[edit_line][1] = '\0';
			key_linepos = 1;
		}
		else
		{
			strcpy(key_lines[edit_line], key_lines[history_line]);
			key_linepos = (int)strlen(key_lines[edit_line]);
		}
		return;
	}

	if (key == K_PGUP || key == K_KP_PGUP )
	{
		con.display -= 2;
		return;
	}

	if (key == K_PGDN || key == K_KP_PGDN ) 
	{
		con.display += 2;
		if (con.display > con.current)
			con.display = con.current;
		return;
	}

	if (key == K_HOME || key == K_KP_HOME )
	{
		if (keydown[K_CTRL] || !key_lines[edit_line][1] || key_linepos == 1)
			con.display = con.current - con.totallines + 10;
		else
			key_linepos = 1;
		return;
	}

	if (key == K_END || key == K_KP_END )
	{
		int		len;

		len = (int)strlen(key_lines[edit_line]);

		if (keydown[K_CTRL] || !key_lines[edit_line][1] || key_linepos == len)
			con.display = con.current;
		else
			key_linepos = len;
		return;
	}
	
	if (key < 32 || key > 127)
		return;	// non printable
		
	if (key_linepos < MAXCMDLINE-1)
	{
		int		last;
		int		length;

		length = (int)strlen(key_lines[edit_line]);

		if (length >= MAXCMDLINE-1)
			return;

		last = key_lines[edit_line][length];

		memmove (key_lines[edit_line] + key_linepos+1, key_lines[edit_line] + key_linepos, length - key_linepos);

		key_lines[edit_line][key_linepos] = (char)key;
		key_linepos++;

		if (!last)
			key_lines[edit_line][length+1] = 0;
	}
}
Beispiel #9
0
/**
 * \brief Interactive line editing and console scrollback.
 * \param[in] key Key that has been pressed.
 */
PRIVATE void Key_Console( int key )
{
	switch( key )
	{
		case K_KP_SLASH:
			key = '/';
			break;

		case K_KP_MINUS:
			key = '-';
			break;

		case K_KP_PLUS:
			key = '+';
			break;

		case K_KP_HOME:
			key = '7';
			break;

		case K_KP_UPARROW:
			key = '8';
			break;

		case K_KP_PGUP:
			key = '9';
			break;

		case K_KP_LEFTARROW:
			key = '4';
			break;

		case K_KP_5:
			key = '5';
			break;

		case K_KP_RIGHTARROW:
			key = '6';
			break;

		case K_KP_END:
			key = '1';
			break;

		case K_KP_DOWNARROW:
			key = '2';
			break;

		case K_KP_PGDN:
			key = '3';
			break;

		case K_KP_INS:
			key = '0';
			break;

		case K_KP_DEL:
			key = '.';
			break;
	}

	if( ( TOUPPER( key ) == 'V' && keydown[K_CTRL] ) ||
		 ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && keydown[K_SHIFT] ) )
	{
		char *cbd;

		if( ( cbd = Sys_GetClipboardData() ) != 0 )
		{
			int iStringLength;

			strtok( cbd, "\n\r\b" );

			iStringLength = strlen( cbd );
			if( iStringLength + key_linepos >= MAXCMDLINE )
			{
				iStringLength = MAXCMDLINE - key_linepos;
			}

			if( iStringLength > 0 )
			{
				cbd[ iStringLength ] = '\0';
				com_strlcat( key_lines[ edit_line ], cbd, sizeof( key_lines[ edit_line ] ) );
				key_linepos += iStringLength;
			}
			MM_FREE( cbd );
		}

		return;
	}

	// ctrl-L clears screen
	if ( key == 'l' && keydown[ K_CTRL ]  )
	{
		Cbuf_AddText( "clear\n" );
		return;
	}

	// enter finishes the line
	if( key == K_ENTER || key == K_KP_ENTER )
	{
		// backslash text are commands, else chat
		if( key_lines[ edit_line ][ 1 ] == '\\' || key_lines[ edit_line ][ 1 ] == '/' )
		{
			Cbuf_AddText( key_lines[ edit_line ] + 2 );	// skip the >
		}
		else
		{
			Cbuf_AddText( key_lines[ edit_line ] + 1 );	// valid command
		}

		Cbuf_AddText( "\n" );
		Com_Printf( "%s\n",key_lines[ edit_line ] );
		edit_line = (edit_line + 1) & 31;
		history_line = edit_line;
		key_lines[ edit_line ][ 0 ] = ']';
		key_linepos = 1;
		if( ClientStatic.state == ca_disconnected )
		{
			Client_Screen_UpdateScreen();	// force an update, because the command
											// may take some time
		}
		return;
	}

	if( key == K_TAB )
	{	// command completion
		CompleteCommand();
		return;
	}

	if( ( key == K_BACKSPACE ) || ( key == K_LEFTARROW ) || ( key == K_KP_LEFTARROW ) || ( ( key == 'h' ) && ( keydown[ K_CTRL ] ) ) )
	{
		if( key_linepos > 1 )
		{
			key_linepos--;
		}
		return;
	}

	if( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) ||
		 ( ( key == 'p' ) && keydown[K_CTRL] ) )
	{
		do
		{
			history_line = (history_line - 1) & 31;

		} while( history_line != edit_line
				&& ! key_lines[ history_line ][ 1 ] );

		if( history_line == edit_line )
		{
			history_line = (edit_line + 1) & 31;
		}
		com_strlcpy( key_lines[ edit_line ], key_lines[ history_line ], sizeof( key_lines[ edit_line ] )  );
		key_linepos = strlen(key_lines[edit_line]);
		return;
	}

	if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) ||
		 ( ( key == 'n' ) && keydown[K_CTRL] ) )
	{
		if( history_line == edit_line )
		{
			return;
		}

		do
		{
			history_line = (history_line + 1) & 31;
		}
		while (history_line != edit_line
			&& !key_lines[history_line][1]);

		if (history_line == edit_line)
		{
			key_lines[edit_line][0] = ']';
			key_linepos = 1;
		}
		else
		{
			com_strlcpy( key_lines[ edit_line ], key_lines[ history_line ], sizeof( key_lines[ edit_line ] ) );
			key_linepos = strlen(key_lines[edit_line]);
		}
		return;
	}


	// console scrolling
	if( key == K_PGUP || key == K_KP_PGUP )
	{
		Con_PageUp();
		return;
	}

	if( key == K_PGDN || key == K_KP_PGDN )
	{
		Con_PageDown();
		return;
	}

	if ( key == K_MWHEELUP)
	{
		Con_PageUp();
		if(keys[K_CTRL].down) {	// hold <ctrl> to accelerate scrolling
			Con_PageUp();
			Con_PageUp();
		}
		return;
	}

	if ( key == K_MWHEELDOWN)
	{
		Con_PageDown();
		if(keys[K_CTRL].down) {	// hold <ctrl> to accelerate scrolling
			Con_PageDown();
			Con_PageDown();
		}
		return;
	}

	// ctrl-home = top of console
	if( key == K_HOME || key == K_KP_HOME )
	{
		Con_Top();
		return;
	}

	// ctrl-end = bottom of console
	if( key == K_END || key == K_KP_END )
	{
		Con_Bottom();
		return;
	}

	if( key < 32 || key > 127 )
	{
		return;	// non printable
	}

	if (key_linepos < MAXCMDLINE-1)
	{
		key_lines[ edit_line ][ key_linepos ] = key;
		key_linepos++;
		key_lines[ edit_line ][ key_linepos ] = 0;
	}

}