r1169 - in trunk: . code/sys

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Sep 6 16:31:30 EDT 2007


Author: tma
Date: 2007-09-06 16:31:30 -0400 (Thu, 06 Sep 2007)
New Revision: 1169

Added:
   trunk/code/sys/con_tty.c
   trunk/code/sys/con_win32.c
Removed:
   trunk/code/sys/tty_console.c
Modified:
   trunk/Makefile
   trunk/code/sys/sys_loadlib.h
   trunk/code/sys/sys_local.h
   trunk/code/sys/sys_main.c
Log:
* Build dedicated server binary on Windows


Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2007-09-06 18:21:10 UTC (rev 1168)
+++ trunk/Makefile	2007-09-06 20:31:30 UTC (rev 1169)
@@ -429,8 +429,8 @@
 
   BINEXT=.exe
 
-  LDFLAGS= -mwindows -lwsock32 -lgdi32 -lwinmm -lole32 -lopengl32
-  CLIENT_LDFLAGS=
+  LDFLAGS= -mwindows -lwsock32 -lwinmm
+  CLIENT_LDFLAGS = -lgdi32 -lole32 -lopengl32
 
   ifeq ($(USE_CURL),1)
     ifneq ($(USE_CURL_DLOPEN),1)
@@ -456,7 +456,6 @@
                     $(LIBSDIR)/win32/libSDLmain.a \
                     $(LIBSDIR)/win32/libSDL.dll.a
 
-  BUILD_SERVER = 0
   BUILD_CLIENT_SMP = 0
 
 else # ifeq mingw32
@@ -1181,9 +1180,6 @@
   $(B)/ded/null_input.o \
   $(B)/ded/null_snddma.o \
   \
-  $(B)/ded/tty_console.o \
-  $(B)/ded/sys_unix.o \
-  \
   $(B)/ded/sys_main.o
 
 ifeq ($(ARCH),i386)
@@ -1214,6 +1210,17 @@
   endif
 endif
 
+ifeq ($(PLATFORM),mingw32)
+  Q3DOBJ += \
+    $(B)/ded/win_resource.o \
+    $(B)/ded/sys_win32.o \
+    $(B)/ded/con_win32.o
+else
+  Q3DOBJ += \
+    $(B)/ded/sys_unix.o \
+    $(B)/ded/con_tty.o
+endif
+
 $(B)/ioq3ded.$(ARCH)$(BINEXT): $(Q3DOBJ)
 	$(echo_cmd) "LD $@"
 	$(Q)$(CC) -o $@ $(Q3DOBJ) $(LDFLAGS)
@@ -1550,6 +1557,9 @@
 $(B)/ded/%.o: $(SYSDIR)/%.c
 	$(DO_DED_CC)
 
+$(B)/ded/%.o: $(SYSDIR)/%.rc
+	$(DO_WINDRES)
+
 $(B)/ded/%.o: $(NDIR)/%.c
 	$(DO_DED_CC)
 

Copied: trunk/code/sys/con_tty.c (from rev 1167, trunk/code/sys/tty_console.c)
===================================================================
--- trunk/code/sys/con_tty.c	                        (rev 0)
+++ trunk/code/sys/con_tty.c	2007-09-06 20:31:30 UTC (rev 1169)
@@ -0,0 +1,440 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+
+This file is part of Quake III Arena source code.
+
+Quake III Arena source code is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the License,
+or (at your option) any later version.
+
+Quake III Arena source code is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Quake III Arena source code; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+===========================================================================
+*/
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+#include <unistd.h>
+#include <signal.h>
+#include <termios.h>
+#include <fcntl.h>
+
+/*
+=============================================================
+tty console routines
+
+NOTE: if the user is editing a line when something gets printed to the early
+console then it won't look good so we provide CON_Hide and CON_Show to be
+called before and after a stdout or stderr output
+=============================================================
+*/
+
+// general flag to tell about tty console mode
+static qboolean ttycon_on = qfalse;
+static int ttycon_hide = 0;
+
+// some key codes that the terminal may be using, initialised on start up
+static int TTY_erase;
+static int TTY_eof;
+
+static struct termios TTY_tc;
+
+static field_t TTY_con;
+
+// This is somewhat of aduplicate of the graphical console history
+// but it's safer more modular to have our own here
+#define CON_HISTORY 32
+static field_t ttyEditLines[ CON_HISTORY ];
+static int hist_current = -1, hist_count = 0;
+
+/*
+==================
+CON_FlushIn
+
+Flush stdin, I suspect some terminals are sending a LOT of shit
+FIXME relevant?
+==================
+*/
+static void CON_FlushIn( void )
+{
+	char key;
+	while (read(0, &key, 1)!=-1);
+}
+
+/*
+==================
+CON_Back
+
+Output a backspace
+
+NOTE: it seems on some terminals just sending '\b' is not enough so instead we
+send "\b \b"
+(FIXME there may be a way to find out if '\b' alone would work though)
+==================
+*/
+static void CON_Back( void )
+{
+	char key;
+	key = '\b';
+	write(1, &key, 1);
+	key = ' ';
+	write(1, &key, 1);
+	key = '\b';
+	write(1, &key, 1);
+}
+
+/*
+==================
+CON_Hide
+
+Clear the display of the line currently edited
+bring cursor back to beginning of line
+==================
+*/
+void CON_Hide( void )
+{
+	if( ttycon_on )
+	{
+		int i;
+		if (ttycon_hide)
+		{
+			ttycon_hide++;
+			return;
+		}
+		if (TTY_con.cursor>0)
+		{
+			for (i=0; i<TTY_con.cursor; i++)
+			{
+				CON_Back();
+			}
+		}
+		CON_Back(); // Delete "]"
+		ttycon_hide++;
+	}
+}
+
+/*
+==================
+CON_Show
+
+Show the current line
+FIXME need to position the cursor if needed?
+==================
+*/
+void CON_Show( void )
+{
+	if( ttycon_on )
+	{
+		int i;
+
+		assert(ttycon_hide>0);
+		ttycon_hide--;
+		if (ttycon_hide == 0)
+		{
+			write( 1, "]", 1 );
+			if (TTY_con.cursor)
+			{
+				for (i=0; i<TTY_con.cursor; i++)
+				{
+					write(1, TTY_con.buffer+i, 1);
+				}
+			}
+		}
+	}
+}
+
+/*
+==================
+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_Back(); // Delete "]"
+		tcsetattr (0, TCSADRAIN, &TTY_tc);
+	}
+
+  // Restore blocking to stdin reads
+  fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) & ~O_NDELAY );
+}
+
+/*
+==================
+Hist_Add
+==================
+*/
+void Hist_Add(field_t *field)
+{
+	int i;
+	assert(hist_count <= CON_HISTORY);
+	assert(hist_count >= 0);
+	assert(hist_current >= -1);
+	assert(hist_current <= hist_count);
+	// make some room
+	for (i=CON_HISTORY-1; i>0; i--)
+	{
+		ttyEditLines[i] = ttyEditLines[i-1];
+	}
+	ttyEditLines[0] = *field;
+	if (hist_count<CON_HISTORY)
+	{
+		hist_count++;
+	}
+	hist_current = -1; // re-init
+}
+
+/*
+==================
+Hist_Prev
+==================
+*/
+field_t *Hist_Prev( void )
+{
+	int hist_prev;
+	assert(hist_count <= CON_HISTORY);
+	assert(hist_count >= 0);
+	assert(hist_current >= -1);
+	assert(hist_current <= hist_count);
+	hist_prev = hist_current + 1;
+	if (hist_prev >= hist_count)
+	{
+		return NULL;
+	}
+	hist_current++;
+	return &(ttyEditLines[hist_current]);
+}
+
+/*
+==================
+Hist_Next
+==================
+*/
+field_t *Hist_Next( void )
+{
+	assert(hist_count <= CON_HISTORY);
+	assert(hist_count >= 0);
+	assert(hist_current >= -1);
+	assert(hist_current <= hist_count);
+	if (hist_current >= 0)
+	{
+		hist_current--;
+	}
+	if (hist_current == -1)
+	{
+		return NULL;
+	}
+	return &(ttyEditLines[hist_current]);
+}
+
+/*
+==================
+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);
+
+	// Make stdin reads non-blocking
+	fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) | O_NDELAY );
+
+	if (isatty(STDIN_FILENO)!=1)
+	{
+		Com_Printf( "stdin is not a tty, tty console mode disabled\n");
+		ttycon_on = qfalse;
+		return;
+	}
+
+	Field_Clear(&TTY_con);
+	tcgetattr (0, &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 sig­
+	nal
+	*/
+	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 (0, TCSADRAIN, &tc);
+	ttycon_on = qtrue;
+}
+
+/*
+==================
+CON_ConsoleInput
+==================
+*/
+char *CON_ConsoleInput( void )
+{
+	// we use this when sending back commands
+	static char text[256];
+	int avail;
+	char key;
+	field_t *history;
+
+	if( ttycon_on )
+	{
+		avail = read(0, &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);
+					strcpy(text, TTY_con.buffer);
+					Field_Clear(&TTY_con);
+					key = '\n';
+					write(1, &key, 1);
+					write( 1, "]", 1 );
+					return text;
+				}
+				if (key == '\t')
+				{
+					CON_Hide();
+					Field_AutoComplete( &TTY_con );
+					CON_Show();
+					return NULL;
+				}
+				avail = read(0, &key, 1);
+				if (avail != -1)
+				{
+					// VT 100 keys
+					if (key == '[' || key == 'O')
+					{
+						avail = read(0, &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;
+			}
+			// push regular character
+			TTY_con.buffer[TTY_con.cursor] = key;
+			TTY_con.cursor++;
+			// print the current line (this is differential)
+			write(1, &key, 1);
+		}
+
+		return NULL;
+	}
+	else
+	{
+		int     len;
+		fd_set  fdset;
+		struct timeval timeout;
+		static qboolean stdin_active;
+
+		if (!com_dedicated || !com_dedicated->value)
+			return NULL;
+
+		if (!stdin_active)
+			return NULL;
+
+		FD_ZERO(&fdset);
+		FD_SET(0, &fdset); // stdin
+		timeout.tv_sec = 0;
+		timeout.tv_usec = 0;
+		if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
+		{
+			return NULL;
+		}
+
+		len = read (0, 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;
+	}
+}

Added: trunk/code/sys/con_win32.c
===================================================================
--- trunk/code/sys/con_win32.c	                        (rev 0)
+++ trunk/code/sys/con_win32.c	2007-09-06 20:31:30 UTC (rev 1169)
@@ -0,0 +1,70 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+
+This file is part of Quake III Arena source code.
+
+Quake III Arena source code is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the License,
+or (at your option) any later version.
+
+Quake III Arena source code is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Quake III Arena source code; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+===========================================================================
+*/
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+/*
+==================
+CON_Hide
+==================
+*/
+void CON_Hide( void )
+{
+}
+
+/*
+==================
+CON_Show
+==================
+*/
+void CON_Show( void )
+{
+}
+
+/*
+==================
+CON_Shutdown
+==================
+*/
+void CON_Shutdown( void )
+{
+}
+
+/*
+==================
+CON_Init
+==================
+*/
+void CON_Init( void )
+{
+}
+
+/*
+==================
+CON_ConsoleInput
+==================
+*/
+char *CON_ConsoleInput( void )
+{
+  return NULL;
+}

Modified: trunk/code/sys/sys_loadlib.h
===================================================================
--- trunk/code/sys/sys_loadlib.h	2007-09-06 18:21:10 UTC (rev 1168)
+++ trunk/code/sys/sys_loadlib.h	2007-09-06 20:31:30 UTC (rev 1169)
@@ -21,11 +21,19 @@
 */
 
 #ifdef DEDICATED
+#	ifdef _WIN32
+#		include <windows.h>
+#		define Sys_LoadLibrary(f) (void*)LoadLibrary(f)
+#		define Sys_UnloadLibrary(h) FreeLibrary((HMODULE)h)
+#		define Sys_LoadFunction(h,fn) (void*)GetProcAddress((HMODULE)h,fn)
+#		define Sys_LibraryError() "unknown"
+#	else
 #	include <dlfcn.h>
-#	define Sys_LoadLibrary(f) dlopen(f,RTLD_NOW)
-#	define Sys_UnloadLibrary(h) dlclose(h)
-#	define Sys_LoadFunction(h,fn) dlsym(h,fn)
-#	define Sys_LibraryError() dlerror()
+#		define Sys_LoadLibrary(f) dlopen(f,RTLD_NOW)
+#		define Sys_UnloadLibrary(h) dlclose(h)
+#		define Sys_LoadFunction(h,fn) dlsym(h,fn)
+#		define Sys_LibraryError() dlerror()
+#endif
 #else
 #	include "SDL.h"
 #	include "SDL_loadso.h"

Modified: trunk/code/sys/sys_local.h
===================================================================
--- trunk/code/sys/sys_local.h	2007-09-06 18:21:10 UTC (rev 1168)
+++ trunk/code/sys/sys_local.h	2007-09-06 20:31:30 UTC (rev 1169)
@@ -28,12 +28,12 @@
 void IN_Frame (void);
 void IN_Shutdown (void);
 
-// TTY console
-void TTY_Hide( void );
-void TTY_Show( void );
-void TTY_Shutdown( void );
-void TTY_Init( void );
-char *TTY_ConsoleInput(void);
+// Console
+void CON_Hide( void );
+void CON_Show( void );
+void CON_Shutdown( void );
+void CON_Init( void );
+char *CON_ConsoleInput(void);
 
 #ifdef MACOS_X
 char *Sys_StripAppBundle( char *pwd );

Modified: trunk/code/sys/sys_main.c
===================================================================
--- trunk/code/sys/sys_main.c	2007-09-06 18:21:10 UTC (rev 1168)
+++ trunk/code/sys/sys_main.c	2007-09-06 20:31:30 UTC (rev 1169)
@@ -113,7 +113,7 @@
 void Sys_ConsoleInputInit( void )
 {
 #ifdef DEDICATED
-	TTY_Init( );
+	CON_Init( );
 #endif
 }
 
@@ -127,7 +127,7 @@
 void Sys_ConsoleInputShutdown( void )
 {
 #ifdef DEDICATED
-	TTY_Shutdown( );
+	CON_Shutdown( );
 #endif
 }
 
@@ -141,7 +141,7 @@
 char *Sys_ConsoleInput(void)
 {
 #ifdef DEDICATED
-	return TTY_ConsoleInput( );
+	return CON_ConsoleInput( );
 #endif
 
 	return NULL;
@@ -224,7 +224,7 @@
 {
 	char Q3color;
 	char *ANSIcolor;
-} TTY_colorTable[ ] =
+} CON_colorTable[ ] =
 {
 	{ COLOR_BLACK,    "30" },
 	{ COLOR_RED,      "31" },
@@ -236,8 +236,8 @@
 	{ COLOR_WHITE,    "0" }
 };
 
-static int TTY_colorTableSize =
-	sizeof( TTY_colorTable ) / sizeof( TTY_colorTable[ 0 ] );
+static int CON_colorTableSize =
+	sizeof( CON_colorTable ) / sizeof( CON_colorTable[ 0 ] );
 
 /*
 =================
@@ -276,11 +276,11 @@
 			if( i < msgLength )
 			{
 				escapeCode = NULL;
-				for( j = 0; j < TTY_colorTableSize; j++ )
+				for( j = 0; j < CON_colorTableSize; j++ )
 				{
-					if( msg[ i ] == TTY_colorTable[ j ].Q3color )
+					if( msg[ i ] == CON_colorTable[ j ].Q3color )
 					{
-						escapeCode = TTY_colorTable[ j ].ANSIcolor;
+						escapeCode = CON_colorTable[ j ].ANSIcolor;
 						break;
 					}
 				}
@@ -310,7 +310,7 @@
 void Sys_Print( const char *msg )
 {
 #ifdef DEDICATED
-	TTY_Hide();
+	CON_Hide();
 #endif
 
 	if( com_ansiColor && com_ansiColor->integer )
@@ -323,7 +323,7 @@
 		fputs(msg, stderr);
 
 #ifdef DEDICATED
-	TTY_Show();
+	CON_Show();
 #endif
 }
 
@@ -338,7 +338,7 @@
 	char    string[1024];
 
 #ifdef DEDICATED
-	TTY_Hide();
+	CON_Hide();
 #endif
 
 	CL_Shutdown ();
@@ -366,13 +366,13 @@
 	va_end (argptr);
 
 #ifdef DEDICATED
-	TTY_Hide();
+	CON_Hide();
 #endif
 
 	fprintf(stderr, "Warning: %s", string);
 
 #ifdef DEDICATED
-	TTY_Show();
+	CON_Show();
 #endif
 }
 

Deleted: trunk/code/sys/tty_console.c
===================================================================
--- trunk/code/sys/tty_console.c	2007-09-06 18:21:10 UTC (rev 1168)
+++ trunk/code/sys/tty_console.c	2007-09-06 20:31:30 UTC (rev 1169)
@@ -1,440 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-===========================================================================
-*/
-
-#include "../qcommon/q_shared.h"
-#include "../qcommon/qcommon.h"
-
-#include <unistd.h>
-#include <signal.h>
-#include <termios.h>
-#include <fcntl.h>
-
-/*
-=============================================================
-tty console routines
-
-NOTE: if the user is editing a line when something gets printed to the early
-console then it won't look good so we provide TTY_Hide and TTY_Show to be
-called before and after a stdout or stderr output
-=============================================================
-*/
-
-// general flag to tell about tty console mode
-static qboolean ttycon_on = qfalse;
-static int ttycon_hide = 0;
-
-// some key codes that the terminal may be using, initialised on start up
-static int TTY_erase;
-static int TTY_eof;
-
-static struct termios TTY_tc;
-
-static field_t TTY_con;
-
-// This is somewhat of aduplicate of the graphical console history
-// but it's safer more modular to have our own here
-#define TTY_HISTORY 32
-static field_t ttyEditLines[ TTY_HISTORY ];
-static int hist_current = -1, hist_count = 0;
-
-/*
-==================
-TTY_FlushIn
-
-Flush stdin, I suspect some terminals are sending a LOT of shit
-FIXME relevant?
-==================
-*/
-static void TTY_FlushIn( void )
-{
-	char key;
-	while (read(0, &key, 1)!=-1);
-}
-
-/*
-==================
-TTY_Back
-
-Output a backspace
-
-NOTE: it seems on some terminals just sending '\b' is not enough so instead we
-send "\b \b"
-(FIXME there may be a way to find out if '\b' alone would work though)
-==================
-*/
-static void TTY_Back( void )
-{
-	char key;
-	key = '\b';
-	write(1, &key, 1);
-	key = ' ';
-	write(1, &key, 1);
-	key = '\b';
-	write(1, &key, 1);
-}
-
-/*
-==================
-TTY_Hide
-
-Clear the display of the line currently edited
-bring cursor back to beginning of line
-==================
-*/
-void TTY_Hide( void )
-{
-	if( ttycon_on )
-	{
-		int i;
-		if (ttycon_hide)
-		{
-			ttycon_hide++;
-			return;
-		}
-		if (TTY_con.cursor>0)
-		{
-			for (i=0; i<TTY_con.cursor; i++)
-			{
-				TTY_Back();
-			}
-		}
-		TTY_Back(); // Delete "]"
-		ttycon_hide++;
-	}
-}
-
-/*
-==================
-TTY_Show
-
-Show the current line
-FIXME need to position the cursor if needed?
-==================
-*/
-void TTY_Show( void )
-{
-	if( ttycon_on )
-	{
-		int i;
-
-		assert(ttycon_hide>0);
-		ttycon_hide--;
-		if (ttycon_hide == 0)
-		{
-			write( 1, "]", 1 );
-			if (TTY_con.cursor)
-			{
-				for (i=0; i<TTY_con.cursor; i++)
-				{
-					write(1, TTY_con.buffer+i, 1);
-				}
-			}
-		}
-	}
-}
-
-/*
-==================
-TTY_Shutdown
-
-Never exit without calling this, or your terminal will be left in a pretty bad state
-==================
-*/
-void TTY_Shutdown( void )
-{
-	if (ttycon_on)
-	{
-		TTY_Back(); // Delete "]"
-		tcsetattr (0, TCSADRAIN, &TTY_tc);
-
-		// Restore blocking to stdin reads
-		fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) & ~O_NDELAY );
-	}
-}
-
-/*
-==================
-Hist_Add
-==================
-*/
-void Hist_Add(field_t *field)
-{
-	int i;
-	assert(hist_count <= TTY_HISTORY);
-	assert(hist_count >= 0);
-	assert(hist_current >= -1);
-	assert(hist_current <= hist_count);
-	// make some room
-	for (i=TTY_HISTORY-1; i>0; i--)
-	{
-		ttyEditLines[i] = ttyEditLines[i-1];
-	}
-	ttyEditLines[0] = *field;
-	if (hist_count<TTY_HISTORY)
-	{
-		hist_count++;
-	}
-	hist_current = -1; // re-init
-}
-
-/*
-==================
-Hist_Prev
-==================
-*/
-field_t *Hist_Prev( void )
-{
-	int hist_prev;
-	assert(hist_count <= TTY_HISTORY);
-	assert(hist_count >= 0);
-	assert(hist_current >= -1);
-	assert(hist_current <= hist_count);
-	hist_prev = hist_current + 1;
-	if (hist_prev >= hist_count)
-	{
-		return NULL;
-	}
-	hist_current++;
-	return &(ttyEditLines[hist_current]);
-}
-
-/*
-==================
-Hist_Next
-==================
-*/
-field_t *Hist_Next( void )
-{
-	assert(hist_count <= TTY_HISTORY);
-	assert(hist_count >= 0);
-	assert(hist_current >= -1);
-	assert(hist_current <= hist_count);
-	if (hist_current >= 0)
-	{
-		hist_current--;
-	}
-	if (hist_current == -1)
-	{
-		return NULL;
-	}
-	return &(ttyEditLines[hist_current]);
-}
-
-/*
-==================
-TTY_Init
-
-Initialize the console input (tty mode if possible)
-==================
-*/
-void TTY_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);
-
-	// Make stdin reads non-blocking
-	fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) | O_NDELAY );
-
-	if (isatty(STDIN_FILENO)!=1)
-	{
-		Com_Printf( "stdin is not a tty, tty console mode disabled\n");
-		ttycon_on = qfalse;
-		return;
-	}
-
-	Field_Clear(&TTY_con);
-	tcgetattr (0, &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 sig­
-	nal
-	*/
-	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 (0, TCSADRAIN, &tc);
-	ttycon_on = qtrue;
-}
-
-/*
-==================
-TTY_ConsoleInput
-==================
-*/
-char *TTY_ConsoleInput( void )
-{
-	// we use this when sending back commands
-	static char text[256];
-	int avail;
-	char key;
-	field_t *history;
-
-	if( ttycon_on )
-	{
-		avail = read(0, &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';
-					TTY_Back();
-				}
-				return NULL;
-			}
-			// check if this is a control char
-			if ((key) && (key) < ' ')
-			{
-				if (key == '\n')
-				{
-					// push it in history
-					Hist_Add(&TTY_con);
-					strcpy(text, TTY_con.buffer);
-					Field_Clear(&TTY_con);
-					key = '\n';
-					write(1, &key, 1);
-					write( 1, "]", 1 );
-					return text;
-				}
-				if (key == '\t')
-				{
-					TTY_Hide();
-					Field_AutoComplete( &TTY_con );
-					TTY_Show();
-					return NULL;
-				}
-				avail = read(0, &key, 1);
-				if (avail != -1)
-				{
-					// VT 100 keys
-					if (key == '[' || key == 'O')
-					{
-						avail = read(0, &key, 1);
-						if (avail != -1)
-						{
-							switch (key)
-							{
-								case 'A':
-									history = Hist_Prev();
-									if (history)
-									{
-										TTY_Hide();
-										TTY_con = *history;
-										TTY_Show();
-									}
-									TTY_FlushIn();
-									return NULL;
-									break;
-								case 'B':
-									history = Hist_Next();
-									TTY_Hide();
-									if (history)
-									{
-										TTY_con = *history;
-									} else
-									{
-										Field_Clear(&TTY_con);
-									}
-									TTY_Show();
-									TTY_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);
-				TTY_FlushIn();
-				return NULL;
-			}
-			// push regular character
-			TTY_con.buffer[TTY_con.cursor] = key;
-			TTY_con.cursor++;
-			// print the current line (this is differential)
-			write(1, &key, 1);
-		}
-
-		return NULL;
-	}
-	else
-	{
-		int     len;
-		fd_set  fdset;
-		struct timeval timeout;
-		static qboolean stdin_active;
-
-		if (!com_dedicated || !com_dedicated->value)
-			return NULL;
-
-		if (!stdin_active)
-			return NULL;
-
-		FD_ZERO(&fdset);
-		FD_SET(0, &fdset); // stdin
-		timeout.tv_sec = 0;
-		timeout.tv_usec = 0;
-		if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
-		{
-			return NULL;
-		}
-
-		len = read (0, 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;
-	}
-}




More information about the quake3-commits mailing list