/* ================== CON_Print ================== */ void CON_Print(const char *msg) { if (!msg[0]) return; CON_Hide(); if(com_ansiColor && com_ansiColor->integer) Sys_AnsiColorPrint(msg); else fputs(msg, stderr); if (!ttycon_on) { // CON_Hide didn't do anything. return; } // Only print prompt when msg ends with a newline, otherwise the console // might get garbled when output does not fit on one line. if (msg[strlen(msg) - 1] == '\n') { CON_Show(); // Run CON_Show the number of times it was deferred. while (ttycon_show_overdue > 0) { CON_Show(); ttycon_show_overdue--; } } else { // Defer calling CON_Show ttycon_show_overdue++; } }
/* ================== CON_Print ================== */ void CON_Print( const char *msg ) { CON_Hide( ); CON_WindowsColorPrint( msg ); CON_Show( ); }
void Console::ToggleVisible() { if (CON_isVisible(mSdlConsole)){ CON_Hide(mSdlConsole); } else { CON_Show(mSdlConsole); } }
/* ================== CON_Print ================== */ void CON_Print(char *string) { CON_Hide(); CON_WindowsColorPrint(string); CON_Show(); }
void con_show(void) { #ifdef CONSOLE if (!con_initialized) con_init_real(); CON_Show(Console); CON_Topmost(Console); #endif }
/* ================== CON_Print ================== */ void CON_Print( const char *msg ) { CON_Hide( ); if( com_ansiColor && com_ansiColor->integer ) Sys_AnsiColorPrint( msg ); else fputs( msg, stderr ); CON_Show( ); }
/* ================== CON_Hide ================== */ void CON_Hide (void) { int realLen; realLen = qconsole_linelen; // remove input line from console output buffer qconsole_linelen = 0; CON_Show(); qconsole_linelen = realLen; }
/* ================== CON_Print ================== */ void CON_Print(const char *msg) { if (com_ansiColor && com_ansiColor->integer) { CON_WindowsColorPrint(msg); } else { fputs(msg, stderr); } CON_Show(); }
/* ================== Hist_Prev ================== */ void Hist_Prev( void ) { if (hist_current == hist_head) return; hist_current = (hist_current + CON_HISTORY - 1) % CON_HISTORY; CON_Hide(); Field_Clear(&TTY_con); memcpy(TTY_con.buffer, ttyEditLines[hist_current], MAX_EDIT_LINE); TTY_con.cursor = strlen(TTY_con.buffer); CON_Show(); }
/* ================== CON_Init Initialize the console input (tty mode if possible) ================== */ void CON_Init(void) { struct termios tc; // If the process is backgrounded (running non interactively) // then SIGTTIN or SIGTOU is emitted, if not caught, turns into a SIGSTP signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); // If SIGCONT is received, reinitialize console signal(SIGCONT, CON_SigCont); // Make stdin reads non-blocking fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK); if(!stdinIsATTY) { Com_Printf("tty console mode disabled\n"); ttycon_on = qfalse; stdin_active = qtrue; return; } Field_Clear(&TTY_con); tcgetattr(STDIN_FILENO, &TTY_tc); TTY_erase = TTY_tc.c_cc[VERASE]; TTY_eof = TTY_tc.c_cc[VEOF]; tc = TTY_tc; /* ECHO: don't echo input characters ICANON: enable canonical mode. This enables the special characters EOF, EOL, EOL2, ERASE, KILL, REPRINT, STATUS, and WERASE, and buffers by lines. ISIG: when any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal */ tc.c_lflag &= ~(ECHO | ICANON); /* ISTRIP strip off bit 8 INPCK enable input parity checking */ tc.c_iflag &= ~(ISTRIP | INPCK); tc.c_cc[VMIN] = 1; tc.c_cc[VTIME] = 0; tcsetattr(STDIN_FILENO, TCSADRAIN, &tc); ttycon_on = qtrue; ttycon_hide = 1; // Mark as hidden, so prompt is shown in CON_Show CON_Show(); }
/* ================== CON_Print ================== */ void CON_Print( const char *msg ) { CON_Hide( ); __android_log_print(ANDROID_LOG_DEBUG, "Quake_DEBUG", "%s", msg); #if 0 if( com_ansiColor && com_ansiColor->integer ) Sys_AnsiColorPrint( msg ); else fputs( msg, stderr ); #endif CON_Show( ); }
/* ================== Hist_Next ================== */ void Hist_Next( void ) { if (hist_current == hist_tail) return; hist_current = (hist_current + 1) % CON_HISTORY; CON_Hide(); Field_Clear(&TTY_con); if (hist_current != hist_tail) memcpy(TTY_con.buffer, ttyEditLines[hist_current], MAX_EDIT_LINE); TTY_con.cursor = strlen(TTY_con.buffer); CON_Show(); }
/* ================== CON_Print_TTY ================== */ void CON_Print_TTY( const char *msg ) { CON_Hide(); if ( ttycon_on && com_ansiColor.Get() ) { CON_AnsiColorPrint( msg ); } else { fputs( msg, stderr ); } CON_Show(); }
/* ================== CON_Print_TTY ================== */ void CON_Print_TTY( const char *msg ) { CON_Hide(); if ( com_ansiColor && com_ansiColor->integer ) { Sys_AnsiColorPrint( msg ); } else { fputs( msg, stderr ); } CON_Show(); }
void Sys_WaitForErrorConfirmation(const char* error) { MSG msg; unsigned int maxwait; threadid_t tid; CON_Show( 1, qtrue ); Sys_CreateNewThread(Sys_ErrorBoxThread, &tid, (void*)error); // wait for the user to quit or wait for max 60 seconds maxwait = Sys_Milliseconds() + 60000; do{ if ( !GetMessage( &msg, NULL, 0, 0 ) ) { break; } TranslateMessage( &msg ); DispatchMessage( &msg ); }while( Sys_Milliseconds() < maxwait ); }
/* ================== 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) { 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'; CON_Back(); } return NULL; } // check if this is a control char if((key) && (key) < ' ') { if(key == '\n') { #ifndef DEDICATED // if not in the game explicitly prepend a slash if needed if (clc.state != CA_ACTIVE && TTY_con.cursor && TTY_con.buffer[0] != '/' && TTY_con.buffer[0] != '\\') { memmove(TTY_con.buffer + 1, TTY_con.buffer, sizeof(TTY_con.buffer) - 1); TTY_con.buffer[0] = '\\'; TTY_con.cursor++; } if (TTY_con.buffer[0] == '/' || TTY_con.buffer[0] == '\\') { Q_strncpyz(text, TTY_con.buffer + 1, sizeof(text)); } else if (TTY_con.cursor) { Com_sprintf(text, sizeof(text), "cmd say %s", TTY_con.buffer); } else { text[0] = '\0'; } // push it in history Hist_Add(&TTY_con); CON_Hide(); Com_Printf("%s%s\n", TTY_CONSOLE_PROMPT, TTY_con.buffer); Field_Clear(&TTY_con); CON_Show(); #else // push it in history Hist_Add(&TTY_con); Q_strncpyz(text, TTY_con.buffer, sizeof(text)); Field_Clear(&TTY_con); key = '\n'; size = write(STDOUT_FILENO, &key, 1); size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT)); #endif 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; // push regular character TTY_con.buffer[TTY_con.cursor] = key; TTY_con.cursor++; // next char will always be '\0' // 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; }
/* ================== CON_ConsoleInput ================== */ char *CON_ConsoleInput (void) { INPUT_RECORD buff[MAXCMDLINE]; 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 >= MAXCMDLINE) { 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; break; } else if (key == VK_UP) { CON_HistPrev(); break; } else if (key == VK_DOWN) { CON_HistNext(); break; } else if (key == VK_TAB) { // command completion field_t f; Field_Clear(&f); Q_strlcpy(f.buffer, qconsole_line, sizeof(f.buffer)); Field_AutoComplete(&f); Q_strlcpy(qconsole_line, f.buffer, sizeof(qconsole_line)); qconsole_linelen = strlen(qconsole_line); break; } if (qconsole_linelen < sizeof(qconsole_line) - 1) { char c = buff[i].Event.KeyEvent.uChar.AsciiChar; if (key == VK_BACK) { int pos = (qconsole_linelen > 0) ? qconsole_linelen - 1 : 0; qconsole_line[pos] = '\0'; qconsole_linelen = pos; } else if (c) { qconsole_line[qconsole_linelen++] = c; 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; }
/* ================== CON_Input ================== */ char *CON_Input( void ) { // we use this when sending back commands static char text[MAX_EDIT_LINE]; int avail; char key; if(ttycon_on) { CON_CheckRep(); avail = read(STDIN_FILENO, &key, 1); if (avail != -1) { // we have something // disable hibernation for ten seconds to workaround console input lagg svs.hibernation.disableUntil = svs.time + 10000; // 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'; CON_Back(); } return NULL; } // check if this is a control char if ((key) && (key) < ' ') { if (key == '\n') { #ifndef DEDICATED if (TTY_con.buffer[0] == '/' || TTY_con.buffer[0] == '\\') { Q_strncpyz(text, TTY_con.buffer + 1, sizeof(text)); } else if (TTY_con.cursor) { Q_strncpyz(text, TTY_con.buffer, sizeof(text)); } else { text[0] = '\0'; } // push it in history Hist_Add(); CON_Hide(); Com_Printf("%s%s\n", TTY_CONSOLE_PROMPT, TTY_con.buffer); Field_Clear(&TTY_con); CON_Show(); #else // push it in history Hist_Add(); Q_strncpyz(text, TTY_con.buffer, sizeof(text)); Field_Clear(&TTY_con); key = '\n'; write(STDOUT_FILENO, &key, 1); write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT)); #endif 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': Hist_Prev(); CON_FlushIn(); return NULL; break; case 'B': Hist_Next(); 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 >= (int)sizeof(text) - 1) return NULL; // push regular character TTY_con.buffer[TTY_con.cursor] = key; TTY_con.cursor++; // next char will always be '\0' // print the current line (this is differential) 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; }
/* ================== 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 size; if(ttycon_on) { 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'; CON_Back(); } return NULL; } // check if this is a control char if ((key) && (key) < ' ') { if (key == '\n') { // push it in history Hist_Add(&TTY_con); Q_strncpyz(text, TTY_con.buffer, sizeof(text)); Field_Clear(&TTY_con); key = '\n'; size = write(1, &key, 1); size = write( 1, "]", 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; // push regular character TTY_con.buffer[TTY_con.cursor] = key; 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; }
/* ================== CON_Print ================== */ void CON_Print( const char *msg ) { fputs( msg, stderr ); CON_Show(); }
/* ================== CON_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; break; } else if ( key == VK_UP ) { Q_strncpyz( qconsole_line, Hist_Prev(), sizeof( qconsole_line ) ); qconsole_linelen = strlen( qconsole_line ); break; } else if ( key == VK_DOWN ) { const char *history = Hist_Next(); if ( history ) { Q_strncpyz( qconsole_line, history, sizeof( qconsole_line ) ); qconsole_linelen = strlen( qconsole_line ); } else if ( qconsole_linelen ) { Hist_Add( qconsole_line ); qconsole_line[ 0 ] = '\0'; qconsole_linelen = 0; } break; } else if ( key == VK_TAB ) { field_t f; Q_strncpyz( f.buffer, qconsole_line, sizeof( f.buffer ) ); Field_AutoComplete( &f, "]" ); Q_strncpyz( qconsole_line, f.buffer, sizeof( qconsole_line ) ); qconsole_linelen = strlen( qconsole_line ); break; } if ( qconsole_linelen < sizeof( qconsole_line ) - 1 ) { char c = buff[ i ].Event.KeyEvent.uChar.AsciiChar; if ( key == VK_BACK ) { int pos = ( qconsole_linelen > 0 ) ? qconsole_linelen - 1 : 0; qconsole_line[ pos ] = '\0'; qconsole_linelen = pos; } else if ( c ) { qconsole_line[ qconsole_linelen++ ] = c; qconsole_line[ qconsole_linelen ] = '\0'; } } } CON_Show(); if ( newlinepos < 0 ) { return NULL; } if ( !qconsole_linelen ) { Com_Printf( "\n" ); return NULL; } Hist_Add( qconsole_line ); Com_Printf( "]%s\n", qconsole_line ); qconsole_linelen = 0; return qconsole_line; }
/* ================== CON_Input_TTY ================== */ char *CON_Input_TTY() { // we use this when sending back commands static char text[ MAX_EDIT_LINE ]; int avail; char key; if ( ttycon_on ) { 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 ) ) { CON_Hide(); TTY_field.DeletePrev(); CON_Show(); CON_FlushIn(); return nullptr; } // check if this is a control char if ( ( key ) && ( key ) < ' ' ) { if ( key == '\n' ) { TTY_field.RunCommand(com_consoleCommand.Get()); WriteToStdout("\n]"); return nullptr; } if ( key == '\t' ) { CON_Hide(); TTY_field.AutoComplete(); CON_Show(); return nullptr; } if ( key == '\x15' ) // ^U { CON_Hide(); TTY_field.Clear(); CON_Show(); return nullptr; } 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': CON_Hide(); TTY_field.HistoryPrev(); CON_Show(); CON_FlushIn(); return nullptr; case 'B': CON_Hide(); TTY_field.HistoryNext(); CON_Show(); CON_FlushIn(); return nullptr; case 'C': return nullptr; case 'D': return nullptr; } } } } CON_FlushIn(); return nullptr; } CON_Hide(); TTY_field.AddChar(key); CON_Show(); } return nullptr; } 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, nullptr, nullptr, &timeout ) == -1 || !FD_ISSET( STDIN_FILENO, &fdset ) ) { return nullptr; } len = read( STDIN_FILENO, text, sizeof( text ) ); if ( len == 0 ) { // eof! stdin_active = false; return nullptr; } if ( len < 1 ) { return nullptr; } text[ len - 1 ] = 0; // rip off the /n and terminate return text; } return nullptr; }
//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; }