create an "input line" object for the console so Con_ProcessInput can be used

in verious contexts
This commit is contained in:
Bill Currie 2001-07-17 16:46:51 +00:00
parent bab80a0648
commit 159bc6147c
5 changed files with 112 additions and 133 deletions

View file

@ -45,6 +45,20 @@ typedef struct
int numlines; // number of non-blank text lines, used for backscroling
} console_t;
typedef struct inputline_s
{
char **lines; // array of lines for input history
int num_lines; // number of lines in arry. 1 == no history
int line_width; // space available in each line. includes \0
char prompt_char; // char placed at the beginning of the line
int edit_line; // current line being edited
int history_line; // current history line
int linepos; // cursor position within the current edit line
int scroll; // beginning of displayed line
void (*complete)(struct inputline_s *); // tab key pressed
void (*enter)(const char *line); // enter key pressed
} inputline_t;
extern console_t con_main;
extern console_t con_chat;
extern console_t *con; // point to either con_main or con_chat
@ -62,7 +76,7 @@ void Con_CheckResize (void);
void Con_Init (const char *plugin_name);
void Con_Shutdown (void);
void Con_Init_Cvars (void);
void Con_ProcessInput (void);
void Con_ProcessInput (inputline_t *il, int ch);
void Con_DrawConsole (int lines);
void Con_DrawDownload (int lines);
void Con_Print (const char *txt);
@ -83,6 +97,9 @@ void Con_CompleteCommandLine(void);
// formatted in columns on the console
void Con_DisplayList(const char **list, int con_linewidth);
inputline_t *Con_CreateInputLine (int lines, int width, char prompt);
void Con_DestroyInputLine (inputline_t *inputline);
extern struct cvar_s *developer;
#endif // __console_h

View file

@ -3,7 +3,7 @@ INCLUDES= -I$(top_srcdir)/include
lib_LTLIBRARIES = libQFconsole.la
common_SOURCES = complete.c console.c list.c
common_SOURCES = complete.c console.c inputline.c list.c
libQFconsole_la_LDFLAGS = -version-info 1:0:0
libQFconsole_la_LIBADD =

View file

@ -33,12 +33,6 @@
# include "config.h"
#endif
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_CURSES_H
# include <curses.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
@ -48,155 +42,123 @@
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/qtypes.h"
#include "QF/sys.h"
#include "QF/keys.h"
static WINDOW *output;
static WINDOW *status;
static WINDOW *input;
static int screen_x, screen_y;
struct inputline_s *
Con_CreateInputLine (int lines, int width, char prompt)
{
int size;
inputline_t *inputline;
char **p;
char *l;
#define MAXCMDLINE 256
char key_lines[32][MAXCMDLINE];
int edit_line;
int history_line;
int key_linepos;
size = sizeof (inputline_t); // space for the header
size += sizeof (char *[lines]); // space for the line pointers
size += lines * width; // space for the lines themselves
inputline = calloc (1, size);
p = (char**)(inputline + 1);
l = (char*)&p[lines];
inputline->num_lines = lines;
inputline->line_width = width;
while (lines--) {
*p++ = l;
l += width;
}
inputline->prompt_char = prompt;
return inputline;
}
void
Con_ProcessInput (void)
Con_DestroyInputLine (inputline_t *inputline)
{
int ch = wgetch (input);
int i;
int curs_x;
char *text = 0;
free (inputline);
}
static int scroll;
void
Con_ProcessInput (inputline_t *il, int ch)
{
int i;
switch (ch) {
case KEY_ENTER:
case '\n':
case '\r':
if (key_lines[edit_line][1] == '/'
&& key_lines[edit_line][2] == '/')
goto no_lf;
else if (key_lines[edit_line][1] == '\\'
|| key_lines[edit_line][1] == '/')
Cbuf_AddText (key_lines[edit_line] + 2);
else
Cbuf_AddText (key_lines[edit_line] + 1);
Cbuf_AddText ("\n");
no_lf:
Con_Printf ("%s\n", key_lines[edit_line]);
edit_line = (edit_line + 1) & 31;
history_line = edit_line;
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
key_linepos = 1;
case K_ENTER:
if (il->enter)
il->enter (il->lines[il->edit_line] + 1);
il->edit_line = (il->edit_line + 1) % il->num_lines;
il->history_line = il->edit_line;
il->lines[il->edit_line][0] = il->prompt_char;
il->lines[il->edit_line][1] = 0;
il->linepos = 1;
break;
case '\t':
Con_CompleteCommandLine();
case K_TAB:
if (il->complete)
il->complete (il);
break;
case KEY_BACKSPACE:
if (key_linepos > 1) {
strcpy (key_lines[edit_line] + key_linepos - 1,
key_lines[edit_line] + key_linepos);
key_linepos--;
case K_BACKSPACE:
if (il->linepos > 1) {
strcpy (il->lines[il->edit_line] + il->linepos - 1,
il->lines[il->edit_line] + il->linepos);
il->linepos--;
}
break;
case KEY_DC:
if (key_linepos < strlen (key_lines[edit_line]))
strcpy (key_lines[edit_line] + key_linepos,
key_lines[edit_line] + key_linepos + 1);
case K_DEL:
if (il->linepos < strlen (il->lines[il->edit_line]))
strcpy (il->lines[il->edit_line] + il->linepos,
il->lines[il->edit_line] + il->linepos + 1);
break;
case KEY_RIGHT:
if (key_linepos < strlen (key_lines[edit_line]))
key_linepos++;
case K_RIGHTARROW:
if (il->linepos < strlen (il->lines[il->edit_line]))
il->linepos++;
break;
case KEY_LEFT:
if (key_linepos > 1)
key_linepos--;
case K_LEFTARROW:
if (il->linepos > 1)
il->linepos--;
break;
case KEY_UP:
case K_UPARROW:
do {
history_line = (history_line - 1) & 31;
} while (history_line != edit_line && !key_lines[history_line][1]);
if (history_line == edit_line)
history_line = (edit_line + 1) & 31;
strcpy (key_lines[edit_line], key_lines[history_line]);
key_linepos = strlen (key_lines[edit_line]);
il->history_line = (il->history_line - 1) % il->num_lines;
} while (il->history_line != il->edit_line
&& !il->lines[il->history_line][1]);
if (il->history_line == il->edit_line)
il->history_line = (il->edit_line + 1) % il->num_lines;
strcpy (il->lines[il->edit_line], il->lines[il->history_line]);
il->linepos = strlen (il->lines[il->edit_line]);
break;
case KEY_DOWN:
if (history_line == edit_line)
case K_DOWNARROW:
if (il->history_line == il->edit_line)
break;
do {
history_line = (history_line + 1) & 31;
} while (history_line != edit_line && !key_lines[history_line][1]);
if (history_line == edit_line) {
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
key_linepos = 1;
il->history_line = (il->history_line + 1) % il->num_lines;
} while (il->history_line != il->edit_line
&& !il->lines[il->history_line][1]);
if (il->history_line == il->edit_line) {
il->lines[il->edit_line][0] = ']';
il->lines[il->edit_line][1] = 0;
il->linepos = 1;
} else {
strcpy (key_lines[edit_line], key_lines[history_line]);
key_linepos = strlen (key_lines[edit_line]);
strcpy (il->lines[il->edit_line], il->lines[il->history_line]);
il->linepos = strlen (il->lines[il->edit_line]);
}
break;
case KEY_PPAGE:
case K_HOME:
il->linepos = 1;
break;
case KEY_NPAGE:
break;
case KEY_HOME:
key_linepos = 1;
break;
case KEY_END:
key_linepos = strlen (key_lines[edit_line]);
case K_END:
il->linepos = strlen (il->lines[il->edit_line]);
break;
default:
if (ch >= ' ' && ch < 127) {
i = strlen (key_lines[edit_line]);
if (i >= MAXCMDLINE - 1)
if (ch >= ' ' && ch < 256 && ch != 127) {
i = strlen (il->lines[il->edit_line]);
if (i >= il->line_width - 1)
break;
// This also moves the ending \0
memmove (key_lines[edit_line] + key_linepos + 1,
key_lines[edit_line] + key_linepos,
i - key_linepos + 1);
key_lines[edit_line][key_linepos] = ch;
key_linepos++;
memmove (il->lines[il->edit_line] + il->linepos + 1,
il->lines[il->edit_line] + il->linepos,
i - il->linepos + 1);
il->lines[il->edit_line][il->linepos] = ch;
il->linepos++;
}
break;
}
i = key_linepos - 1;
if (scroll > i)
scroll = i;
if (scroll < i - (screen_x - 2) + 1)
scroll = i - (screen_x - 2) + 1;
text = key_lines[edit_line] + scroll + 1;
if ((int)strlen (text) < screen_x - 2) {
scroll = strlen (key_lines[edit_line] + 1) - (screen_x - 2);
if (scroll < 0)
scroll = 0;
text = key_lines[edit_line] + scroll + 1;
}
curs_x = key_linepos - scroll;
wmove (input, 0, 0);
if (scroll) {
waddch (input, '<');
} else {
waddch (input, key_lines[edit_line][0]);
}
for (i = 0; i < screen_x - 2 && *text; i++)
waddch (input, *text++);
while (i++ < screen_x - 2)
waddch (input, ' ');
if (*text) {
waddch (input, '>');
} else {
waddch (input, ' ');
}
wmove (input, 0, curs_x);
touchline (stdscr, screen_y - 1, 1);
wrefresh (input);
}

View file

@ -160,15 +160,15 @@ Con_Print (const char *txt)
}
void
Con_ProcessInput (void)
Con_ProcessInput (inputline_t *il, int ch)
{
int ch = wgetch (input);
int i;
int curs_x;
char *text = 0;
static int scroll;
ch = wgetch (input);
switch (ch) {
case KEY_ENTER:
case '\n':

View file

@ -1442,7 +1442,7 @@ SV_CheckTimeouts (void)
void
SV_GetConsoleCommands (void)
{
Con_ProcessInput ();
Con_ProcessInput (0, 0); //XXX parms not used yet
}
/*
@ -1552,7 +1552,7 @@ SV_Frame (float time)
svs.stats.packets = 0;
svs.stats.count = 0;
}
Con_ProcessInput (); //XXX evil hack to get the cursor in the right place
Con_ProcessInput (0, 0); //XXX evil hack to get the cursor in the right place
}
/*