/* ==================== Console_Key Handles history and console scrollback ==================== */ void Console_Key (int key) { // ctrl-L clears screen if ( key == 'l' && keys[K_CTRL].down ) { Cbuf_AddText ("clear\n"); return; } // enter finishes the line if ( key == K_ENTER || key == K_KP_ENTER ) { // if not in the game explicitly prepend a slash if needed if ( cls.state != CA_ACTIVE && g_consoleField.buffer[0] != '\0' && g_consoleField.buffer[0] != '\\' && g_consoleField.buffer[0] != '/' ) { char temp[MAX_EDIT_LINE-1]; Q_strncpyz( temp, g_consoleField.buffer, sizeof( temp ) ); Com_sprintf( g_consoleField.buffer, sizeof( g_consoleField.buffer ), "\\%s", temp ); g_consoleField.cursor++; } Com_Printf ( "]%s\n", g_consoleField.buffer ); // leading slash is an explicit command if ( g_consoleField.buffer[0] == '\\' || g_consoleField.buffer[0] == '/' ) { Cbuf_AddText( g_consoleField.buffer+1 ); // valid command Cbuf_AddText ("\n"); } else { // other text will be chat messages if ( !g_consoleField.buffer[0] ) { return; // empty lines just scroll the console without adding to history } else { Cbuf_AddText ("cmd say "); Cbuf_AddText( g_consoleField.buffer ); Cbuf_AddText ("\n"); } } // copy line to history buffer Con_SaveField( &g_consoleField ); Field_Clear( &g_consoleField ); g_consoleField.widthInChars = g_console_field_width; if ( cls.state == CA_DISCONNECTED ) { SCR_UpdateScreen (); // force an update, because the command } // may take some time return; } // command completion if (key == K_TAB) { Field_AutoComplete(&g_consoleField); return; } // command history (ctrl-p ctrl-n for unix style) if ( (key == K_MWHEELUP && keys[K_SHIFT].down) || ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) || ( ( tolower(key) == 'p' ) && keys[K_CTRL].down ) ) { Con_HistoryGetPrev( &g_consoleField ); g_consoleField.widthInChars = g_console_field_width; return; } if ( (key == K_MWHEELDOWN && keys[K_SHIFT].down) || ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) || ( ( tolower(key) == 'n' ) && keys[K_CTRL].down ) ) { Con_HistoryGetNext( &g_consoleField ); g_consoleField.widthInChars = g_console_field_width; return; } // console scrolling if ( key == K_PGUP ) { if ( keys[K_CTRL].down ) { // hold <ctrl> to accelerate scrolling Con_PageUp( 0 ); // by one visible page } else { Con_PageUp( 1 ); } return; } if ( key == K_PGDN ) { if ( keys[K_CTRL].down ) { // hold <ctrl> to accelerate scrolling Con_PageDown( 0 ); // by one visible page } else { Con_PageDown( 1 ); } return; } if ( key == K_MWHEELUP ) { //----(SA) added some mousewheel functionality to the console if ( keys[K_CTRL].down ) { // hold <ctrl> to accelerate scrolling Con_PageUp( 4 ); } else { Con_PageUp( 1 ); } return; } if ( key == K_MWHEELDOWN ) { //----(SA) added some mousewheel functionality to the console if ( keys[K_CTRL].down ) { // hold <ctrl> to accelerate scrolling Con_PageDown( 4 ); } else { Con_PageDown( 1 ); } return; } // ctrl-home = top of console if ( key == K_HOME && keys[K_CTRL].down ) { Con_Top(); return; } // ctrl-end = bottom of console if ( key == K_END && keys[K_CTRL].down ) { Con_Bottom(); return; } // pass to the normal editline routine Field_KeyDownEvent( &g_consoleField, key ); }
/* ==================== Console_Key Handles history and console scrollback ==================== */ void Console_Key ( int key, qboolean down ) { if ( !down ) { return; } if ( key & K_CHAR_FLAG ) { key &= ~K_CHAR_FLAG; MField_CharEvent( &g_consoleField, key ); return; } // ctrl-L clears screen if ( key == 'l' && trap_Key_IsDown( K_CTRL ) ) { trap_Cmd_ExecuteText( EXEC_APPEND, "clear\n" ); return; } // enter finishes the line if ( key == K_ENTER || key == K_KP_ENTER ) { uiClientState_t cls; trap_GetClientState( &cls ); // if not in the game explicitly prepend a slash if needed if ( cls.connState != CA_ACTIVE && con_autochat.integer && g_consoleField.buffer[0] && g_consoleField.buffer[0] != '\\' && g_consoleField.buffer[0] != '/' ) { char temp[MAX_EDIT_LINE-1]; Q_strncpyz( temp, g_consoleField.buffer, sizeof( temp ) ); Com_sprintf( g_consoleField.buffer, sizeof( g_consoleField.buffer ), "\\%s", temp ); g_consoleField.cursor++; } Com_Printf ( "]%s\n", g_consoleField.buffer ); // leading slash is an explicit command if ( g_consoleField.buffer[0] == '\\' || g_consoleField.buffer[0] == '/' ) { trap_Cmd_ExecuteText( EXEC_APPEND, g_consoleField.buffer+1 ); // valid command trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); } else { // other text will be chat messages if ( !g_consoleField.buffer[0] ) { return; // empty lines just scroll the console without adding to history } else { if ( con_autochat.integer ) { trap_Cmd_ExecuteText( EXEC_APPEND, "cmd say " ); } trap_Cmd_ExecuteText( EXEC_APPEND, g_consoleField.buffer ); trap_Cmd_ExecuteText( EXEC_APPEND, "\n" ); } } // copy line to history buffer historyEditLines[nextHistoryLine % COMMAND_HISTORY] = g_consoleField; nextHistoryLine++; historyLine = nextHistoryLine; MField_Clear( &g_consoleField ); g_consoleField.widthInChars = g_console_field_width; CG_SaveConsoleHistory( ); if ( cls.connState == CA_DISCONNECTED ) { trap_UpdateScreen(); // force an update, because the command } // may take some time return; } // command completion if (key == K_TAB) { char newbuf[MAX_EDIT_LINE]; trap_Cmd_AutoComplete( g_consoleField.buffer, newbuf, sizeof ( newbuf ) ); if ( strcmp( newbuf, g_consoleField.buffer ) != 0 ) { Q_strncpyz( g_consoleField.buffer, newbuf, sizeof ( g_consoleField.buffer ) ); g_consoleField.cursor = strlen( g_consoleField.buffer ); } return; } // command history (ctrl-p ctrl-n for unix style) if ( ( key == K_MWHEELUP && trap_Key_IsDown( K_SHIFT ) ) || ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) || ( ( tolower(key) == 'p' ) && trap_Key_IsDown( K_CTRL ) ) ) { if ( nextHistoryLine - historyLine < COMMAND_HISTORY && historyLine > 0 ) { historyLine--; } g_consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; return; } if ( ( key == K_MWHEELDOWN && trap_Key_IsDown( K_SHIFT ) ) || ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) || ( ( tolower(key) == 'n' ) && trap_Key_IsDown( K_CTRL ) ) ) { historyLine++; if (historyLine >= nextHistoryLine) { historyLine = nextHistoryLine; MField_Clear( &g_consoleField ); g_consoleField.widthInChars = g_console_field_width; return; } g_consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; 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) { //----(SA) added some mousewheel functionality to the console Con_PageUp(); if ( trap_Key_IsDown( K_CTRL ) ) { // hold <ctrl> to accelerate scrolling Con_PageUp(); Con_PageUp(); } return; } if ( key == K_MWHEELDOWN) { //----(SA) added some mousewheel functionality to the console Con_PageDown(); if ( trap_Key_IsDown( K_CTRL ) ) { // hold <ctrl> to accelerate scrolling Con_PageDown(); Con_PageDown(); } return; } // ctrl-home = top of console if ( ( key == K_HOME || key == K_KP_HOME ) && trap_Key_IsDown( K_CTRL ) ) { Con_Top(); return; } // ctrl-end = bottom of console if ( ( key == K_END || key == K_KP_END ) && trap_Key_IsDown( K_CTRL ) ) { Con_Bottom(); return; } // pass to the normal editline routine MField_KeyDownEvent( &g_consoleField, key ); }
/** * \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; } }