mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
create an "input line" object for the console so Con_ProcessInput can be used
in verious contexts
This commit is contained in:
parent
bab80a0648
commit
159bc6147c
5 changed files with 112 additions and 133 deletions
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue