>
> you've reverted some of these:
>
> size = write(...);
>
> this produces warnings as write is marked as
> __attribute_warn_unused_result__
>
>
OK, I reverted those changes back to the original. Patch attached.
Compiled and tested, no warnings due to the change.
One question. I actually ended up editing Makefile to temporarily add:
--- Makefile (revision 1802)
+++ Makefile (working copy)
@@ -258,7 +258,7 @@
endif
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
- -pipe -DUSE_ICON
+ -pipe -DUSE_ICON -D_FORTIFY_SOURCE=1
CLIENT_CFLAGS = $(SDL_CFLAGS)
SERVER_CFLAGS =
Is there any better way to do this? I tried environment variables and
Makefile.local, but that didn't work. I am kind of new to Makefile and C
programming; I come from a Java background (and I'm ashamed to say it).
Index: code/sys/con_tty.c
===================================================================
--- code/sys/con_tty.c (revision 1802)
+++ code/sys/con_tty.c (working copy)
@@ -45,6 +45,7 @@
// general flag to tell about tty console mode
static qboolean ttycon_on = qfalse;
static int ttycon_hide = 0;
+static int ttycon_show_overdue = 0; // used only by CON_Print()
// some key codes that the terminal may be using, initialised on start up
static int TTY_erase;
@@ -60,6 +61,23 @@
static field_t ttyEditLines[ CON_HISTORY ];
static int hist_current = -1, hist_count = 0;
+// Note: TTY_CONSOLE_PROMPT can contain any number of characters.
+#ifdef DEDICATED
+#define TTY_CONSOLE_PROMPT "]"
+#else
+// Right now the in-game console has the "]" prompt.
+// We choose a different prompt for the tty console for the following reasons:
+// 1. Both tty and in-game console commands get printed to tty output, so it may be
+// confusing to tell where a command came from.
+// 2. tty and in-game consoles have an independent history buffers.
+// 3. When connected to a server, a command in the in-game console not preceded
+// by a slash is a chat (not so for tty).
+#define TTY_CONSOLE_PROMPT "ioq3-tty]"
+// Note: In order to cause tty commands to be visible in the in-game console, you
+// must define TTY_COMMANDS_VISIBLE_IN_GAME.
+#define TTY_COMMANDS_VISIBLE_IN_GAME
+#endif
+
/*
==================
CON_FlushIn
@@ -123,7 +141,9 @@
CON_Back();
}
}
- CON_Back(); // Delete "]"
+ for (i = strlen(TTY_CONSOLE_PROMPT); i > 0; i--) {
+ CON_Back();
+ }
ttycon_hide++;
}
}
@@ -147,7 +167,7 @@
if (ttycon_hide == 0)
{
size_t 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++)
@@ -168,9 +188,12 @@
*/
void CON_Shutdown( void )
{
+ int i;
if (ttycon_on)
{
- CON_Back(); // Delete "]"
+ for (i = strlen(TTY_CONSOLE_PROMPT); i > 0; i--) {
+ CON_Back();
+ }
tcsetattr (STDIN_FILENO, TCSADRAIN, &TTY_tc);
}
@@ -186,6 +209,8 @@
void Hist_Add(field_t *field)
{
int i;
+ if (!field->cursor) { return; } // Don't save blank lines in history.
+ // We could have checked field->buffer[0] instead.
assert(hist_count <= CON_HISTORY);
assert(hist_count >= 0);
assert(hist_current >= -1);
@@ -315,6 +340,8 @@
tc.c_cc[VTIME] = 0;
tcsetattr (STDIN_FILENO, TCSADRAIN, &tc);
ttycon_on = qtrue;
+ CON_Hide(); // These two lines cause the tty prompt to
+ CON_Show(); // appear right away. It's a problem on clients.
}
/*
@@ -354,14 +381,58 @@
{
if (key == '\n')
{
- // push it in history
+#ifndef DEDICATED
+ if (TTY_con.cursor && // We can either check TTY_con.cursor or
+ // TTY_con.buffer[0]. I'm not sure which one
+ // is cleaner. You can decide that. Same
+ // goes for the last boolean below - we could
+ // check strlen(TTY_con.buffer) there.
+ TTY_con.buffer[0] != '/' &&
+ TTY_con.buffer[0] != '\\' &&
+ TTY_con.cursor < MAX_EDIT_LINE - 1) {
+ // Add backslash to beginning of command to make it
+ // clear that only commands are accepted. Also this is consistent
+ // with the autocomplete feature, which adds a backslash. We don't
+ // add the backslash if the command buffer is at capacity because
+ // that would truncate the command (poor user experience). Prepending
+ // the backslash is not necessary; it's only to improve user experience.
+ text[0] = '\\';
+ Q_strncpyz(text + 1, TTY_con.buffer, sizeof(text) - 1);
+ Q_strncpyz(TTY_con.buffer, text, sizeof(TTY_con.buffer));
+ TTY_con.cursor++;
+ }
+ else {
+ Q_strncpyz(text, TTY_con.buffer, sizeof(text));
+ }
Hist_Add(&TTY_con);
+#ifdef TTY_COMMANDS_VISIBLE_IN_GAME
+ CON_Hide();
+ Com_Printf("%s%s\n", TTY_CONSOLE_PROMPT, TTY_con.buffer);
+ Field_Clear(&TTY_con);
+ CON_Show();
+#else
+ CON_Hide(); // make sure the added
+ CON_Show(); // backslash shows up
+ Field_Clear(&TTY_con);
+ key = '\n';
+ size = write(STDOUT_FILENO, &key, 1);
+ size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT));
+#endif
+ if (text[0] == '/' || text[0] == '\\') { // explicit command
+ return text + 1;
+ }
+ else {
+ return text;
+ }
+#else // DEDICATED - Below is the original code before Rambetter's fixes.
+ 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 );
+ size = write(STDOUT_FILENO, &key, 1);
+ size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT));
return text;
+#endif
}
if (key == '\t')
{
@@ -422,7 +493,7 @@
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);
}
@@ -465,6 +536,8 @@
*/
void CON_Print( const char *msg )
{
+ if (!msg[0]) return;
+
CON_Hide( );
if( com_ansiColor && com_ansiColor->integer )
@@ -472,5 +545,30 @@
else
fputs( msg, stderr );
- CON_Show( );
+ // The special logic below prevents printing the tty prompt
+ // when this CON_Print() doesn't end with a newline. The problem
+ // with printing the prompt in this case is that the console
+ // might get garbled when output does not fit on one line,
+ // especially if the prompt is more than one character.
+ // Note that regardless of the hide status of the console,
+ // a user will always be able to input and execute commands [when the
+ // console is turned on]. So even if the newline never arrives,
+ // the user will be able to type commands and see them typed
+ // after the text on the current line (although not pretty).
+ if (!ttycon_on) {
+ // Our CON_Hide() above didn't do anything so we can just do nothing here.
+ return;
+ }
+ // From here on it's guaranteed that CON_Hide() did increment ttycon_hide.
+ if (msg[strlen(msg) - 1] == '\n') { // ends with newline
+ CON_Show();
+ while (ttycon_show_overdue > 0) {
+ CON_Show();
+ ttycon_show_overdue--;
+ }
+ }
+ else { // This means that ttycon_hide was incremented by CON_Hide() above
+ // so we owe the system one CON_Show() later on.
+ ttycon_show_overdue++;
+ }
}
_______________________________________________
ioquake3 mailing list
[email protected]
http://lists.ioquake.org/listinfo.cgi/ioquake3-ioquake.org
By sending this message I agree to love ioquake3 and libsdl.