/* ==================== 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 ); }
/* ==================== 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 ); }
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); }
/* ================ 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 ); }
/* =============== 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 ); }
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; }
/* ==================== 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; }
/* ==================== 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; } }
/** * \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; } }