summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Middleton <zturtleman@gmail.com>2012-02-06 21:05:57 +0000
committerTim Angus <tim@ngus.net>2013-01-12 20:17:25 +0000
commit89dbcd9f595d184a81d3991aee7d6394b2b4431f (patch)
tree2fba708b7a5d8aa40560e95b9ad35002db1508cc
parent99d35cf1347a5bc4f25c749149e811763e59e5ef (diff)
Unix clients can now enter commands from tty console. Patch by Rambetter with some edits by me. (#4799)
-rw-r--r--Makefile9
-rw-r--r--src/sys/con_tty.c84
2 files changed, 86 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 2ea8698e..2e621c90 100644
--- a/Makefile
+++ b/Makefile
@@ -1331,10 +1331,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 \
diff --git a/src/sys/con_tty.c b/src/sys/con_tty.c
index 0d8da734..212f038a 100644
--- a/src/sys/con_tty.c
+++ b/src/sys/con_tty.c
@@ -26,6 +26,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>
@@ -47,6 +51,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;
@@ -62,6 +67,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
@@ -125,7 +138,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++;
}
}
@@ -149,7 +165,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++)
@@ -172,7 +188,7 @@ void CON_Shutdown( void )
{
if (ttycon_on)
{
- CON_Back(); // Delete "]"
+ CON_Hide();
tcsetattr (STDIN_FILENO, TCSADRAIN, &TTY_tc);
}
@@ -188,6 +204,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);
@@ -317,6 +338,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();
}
/*
@@ -356,13 +379,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')
@@ -424,7 +473,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);
}
@@ -467,6 +516,9 @@ CON_Print
*/
void CON_Print( const char *msg )
{
+ if (!msg[0])
+ return;
+
CON_Hide( );
if( com_ansiColor && com_ansiColor->integer )
@@ -474,5 +526,25 @@ void CON_Print( const char *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++;
+ }
}