Skip to content

Commit

Permalink
Unix clients can now enter commands from tty console. Patch by Rambet…
Browse files Browse the repository at this point in the history
…ter with some edits by me. (#4799)
  • Loading branch information
zturtleman committed Feb 6, 2012
1 parent 3241ca6 commit c843778
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 7 deletions.
9 changes: 8 additions & 1 deletion Makefile
Expand Up @@ -1443,10 +1443,17 @@ Q3OBJ = \
$(B)/client/sdl_input.o \
$(B)/client/sdl_snd.o \
\
$(B)/client/con_passive.o \
$(B)/client/con_log.o \
$(B)/client/sys_main.o

ifeq ($(PLATFORM),mingw32)
Q3OBJ += \
$(B)/client/con_passive.o
else
Q3OBJ += \
$(B)/client/con_tty.o
endif

Q3ROBJ = \
$(B)/renderer/tr_animation.o \
$(B)/renderer/tr_backend.o \
Expand Down
84 changes: 78 additions & 6 deletions code/sys/con_tty.c
Expand Up @@ -24,6 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#include "sys_local.h"

#ifndef DEDICATED
#include "../client/client.h"
#endif

#include <unistd.h>
#include <signal.h>
#include <termios.h>
Expand All @@ -45,6 +49,7 @@ static qboolean stdin_active;
// general flag to tell about tty console mode
static qboolean ttycon_on = qfalse;
static int ttycon_hide = 0;
static int ttycon_show_overdue = 0;

// some key codes that the terminal may be using, initialised on start up
static int TTY_erase;
Expand All @@ -60,6 +65,14 @@ static field_t TTY_con;
static field_t ttyEditLines[ CON_HISTORY ];
static int hist_current = -1, hist_count = 0;

#ifndef DEDICATED
// Don't use "]" as it would be the same as in-game console,
// this makes it clear where input came from.
#define TTY_CONSOLE_PROMPT "tty]"
#else
#define TTY_CONSOLE_PROMPT "]"
#endif

/*
==================
CON_FlushIn
Expand Down Expand Up @@ -123,7 +136,10 @@ static void CON_Hide( void )
CON_Back();
}
}
CON_Back(); // Delete "]"
// Delete prompt
for (i = strlen(TTY_CONSOLE_PROMPT); i > 0; i--) {
CON_Back();
}
ttycon_hide++;
}
}
Expand All @@ -147,7 +163,7 @@ static void CON_Show( void )
if (ttycon_hide == 0)
{
size_t UNUSED_VAR size;
size = write(STDOUT_FILENO, "]", 1);
size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT));
if (TTY_con.cursor)
{
for (i=0; i<TTY_con.cursor; i++)
Expand All @@ -170,7 +186,7 @@ void CON_Shutdown( void )
{
if (ttycon_on)
{
CON_Back(); // Delete "]"
CON_Hide();
tcsetattr (STDIN_FILENO, TCSADRAIN, &TTY_tc);
}

Expand All @@ -186,6 +202,11 @@ Hist_Add
void Hist_Add(field_t *field)
{
int i;

// Don't save blank lines in history.
if (!field->cursor)
return;

assert(hist_count <= CON_HISTORY);
assert(hist_count >= 0);
assert(hist_current >= -1);
Expand Down Expand Up @@ -315,6 +336,8 @@ void CON_Init( void )
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();
}

/*
Expand Down Expand Up @@ -354,13 +377,39 @@ char *CON_Input( void )
{
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, "]", 1);
size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT));
#endif
return text;
}
if (key == '\t')
Expand Down Expand Up @@ -422,7 +471,7 @@ char *CON_Input( void )
return NULL;
// push regular character
TTY_con.buffer[TTY_con.cursor] = key;
TTY_con.cursor++;
TTY_con.cursor++; // next char will always be '\0'
// print the current line (this is differential)
size = write(STDOUT_FILENO, &key, 1);
}
Expand Down Expand Up @@ -465,12 +514,35 @@ 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 );

CON_Show( );
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++;
}
}

0 comments on commit c843778

Please sign in to comment.