/* ================== 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(); }
/* ================== CON_Shutdown ================== */ void CON_Shutdown (void) { CON_Hide(); SetConsoleMode(qconsole_hin, qconsole_orig_mode); SetConsoleCursorInfo(qconsole_hout, &qconsole_orig_cursorinfo); SetConsoleTextAttribute(qconsole_hout, qconsole_attrib); CloseHandle(qconsole_hout); CloseHandle(qconsole_hin); }
/* ================== 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_Shutdown Never exit without calling this, or your terminal will be left in a pretty bad state ================== */ void CON_Shutdown(void) { if(ttycon_on) { CON_Hide(); tcsetattr(STDIN_FILENO, TCSADRAIN, &TTY_tc); } // Restore blocking to stdin reads fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) & ~O_NONBLOCK); }
/* ================== 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_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(); }
/* ================== 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_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; }
/* Takes keys from the keyboard and inputs them to the console If the event was not handled (i.e. WM events or unknown ctrl-shift sequences) the function returns the event for further processing. */ int CON_Events(int event) { if(Topmost == NULL) return event; if(!CON_isVisible(Topmost)) return event; if(event & KEY_CTRLED) { //CTRL pressed switch(event & ~KEY_CTRLED) { case KEY_A: Cursor_Home(Topmost); break; case KEY_E: Cursor_End(Topmost); break; case KEY_C: Clear_Command(Topmost); break; case KEY_L: Clear_History(Topmost); CON_UpdateConsole(Topmost); break; default: return event; } } else if(event & KEY_ALTED) { //the console does not handle ALT combinations! return event; } else { //first of all, check if the console hide key was pressed if(event == Topmost->HideKey) { CON_Hide(Topmost); return 0; } switch (event & 0xff) { case KEY_LSHIFT: case KEY_RSHIFT: return event; case KEY_HOME: if(event & KEY_SHIFTED) { Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; CON_UpdateConsole(Topmost); } else { Cursor_Home(Topmost); } break; case KEY_END: if(event & KEY_SHIFTED) { Topmost->ConsoleScrollBack = 0; CON_UpdateConsole(Topmost); } else { Cursor_End(Topmost); } break; case KEY_PAGEUP: Topmost->ConsoleScrollBack += CON_LINE_SCROLL; if(Topmost->ConsoleScrollBack > Topmost->LineBuffer-1) Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; CON_UpdateConsole(Topmost); break; case KEY_PAGEDOWN: Topmost->ConsoleScrollBack -= CON_LINE_SCROLL; if(Topmost->ConsoleScrollBack < 0) Topmost->ConsoleScrollBack = 0; CON_UpdateConsole(Topmost); break; case KEY_UP: Command_Up(Topmost); break; case KEY_DOWN: Command_Down(Topmost); break; case KEY_LEFT: Cursor_Left(Topmost); break; case KEY_RIGHT: Cursor_Right(Topmost); break; case KEY_BACKSP: Cursor_BSpace(Topmost); break; case KEY_DELETE: Cursor_Del(Topmost); break; case KEY_INSERT: Topmost->InsMode = 1-Topmost->InsMode; break; case KEY_TAB: CON_TabCompletion(Topmost); break; case KEY_ENTER: if(strlen(Topmost->Command) > 0) { CON_NewLineCommand(Topmost); // copy the input into the past commands strings strcpy(Topmost->CommandLines[0], Topmost->Command); // display the command including the prompt CON_Out(Topmost, "%s%s", Topmost->Prompt, Topmost->Command); CON_UpdateConsole(Topmost); CON_Execute(Topmost, Topmost->Command); //printf("Command: %s\n", Topmost->Command); Clear_Command(Topmost); Topmost->CommandScrollBack = -1; } break; case KEY_ESC: //deactivate Console if (event & KEY_SHIFTED) { CON_Hide(Topmost); return 0; } break; default: if(Topmost->InsMode) Cursor_Add(Topmost, event); else { Cursor_Add(Topmost, event); Cursor_Del(Topmost); } } } return 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 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_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; }
/* Takes keys from the keyboard and inputs them to the console If the event was not handled (i.e. WM events or unknown ctrl-shift sequences) the function returns the event for further processing. */ SDL_Event* CON_Events(SDL_Event *event) { if(Topmost == NULL) return event; if(!CON_isVisible(Topmost)) return event; if(event->type == SDL_KEYDOWN) { if(event->key.keysym.mod & KMOD_CTRL) { /* CTRL pressed */ switch(event->key.keysym.sym) { case SDLK_a: Cursor_Home(Topmost); break; case SDLK_e: Cursor_End(Topmost); break; case SDLK_c: Clear_Command(Topmost); break; case SDLK_l: Clear_History(Topmost); CON_UpdateConsole(Topmost); break; default: return event; } } else if(event->key.keysym.mod & KMOD_ALT) { /* the console does not handle ALT combinations! */ return event; } else { /* first of all, check if the console hide key was pressed */ if(event->key.keysym.sym == Topmost->HideKey) { CON_Hide(Topmost); return NULL; } switch (event->key.keysym.sym) { case SDLK_HOME: if(event->key.keysym.mod & KMOD_SHIFT) { Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; CON_UpdateConsole(Topmost); } else { Cursor_Home(Topmost); } break; case SDLK_END: if(event->key.keysym.mod & KMOD_SHIFT) { Topmost->ConsoleScrollBack = 0; CON_UpdateConsole(Topmost); } else { Cursor_End(Topmost); } break; case SDLK_PAGEUP: Topmost->ConsoleScrollBack += CON_LINE_SCROLL; if(Topmost->ConsoleScrollBack > Topmost->LineBuffer-1) Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; CON_UpdateConsole(Topmost); break; case SDLK_PAGEDOWN: Topmost->ConsoleScrollBack -= CON_LINE_SCROLL; if(Topmost->ConsoleScrollBack < 0) Topmost->ConsoleScrollBack = 0; CON_UpdateConsole(Topmost); break; case SDLK_UP: Command_Up(Topmost); break; case SDLK_DOWN: Command_Down(Topmost); break; case SDLK_LEFT: Cursor_Left(Topmost); break; case SDLK_RIGHT: Cursor_Right(Topmost); break; case SDLK_BACKSPACE: Cursor_BSpace(Topmost); break; case SDLK_DELETE: Cursor_Del(Topmost); break; case SDLK_INSERT: Topmost->InsMode = 1-Topmost->InsMode; break; case SDLK_TAB: CON_TabCompletion(Topmost); break; case SDLK_RETURN: if(strlen(Topmost->Command) > 0) { CON_NewLineCommand(Topmost); /* copy the input into the past commands strings */ strcpy(Topmost->CommandLines[0], Topmost->Command); /* display the command including the prompt */ CON_Out(Topmost, "%s%s", Topmost->Prompt, Topmost->Command); CON_Execute(Topmost, Topmost->Command); /* printf("Command: %s\n", Topmost->Command); */ Clear_Command(Topmost); Topmost->CommandScrollBack = -1; } break; case SDLK_ESCAPE: /* deactivate Console */ CON_Hide(Topmost); return NULL; default: if(Topmost->InsMode) Cursor_Add(Topmost, event); else { Cursor_Add(Topmost, event); Cursor_Del(Topmost); } } } return NULL; } return event; }