📄 window.c
字号:
head 2.3;access;symbols;locks; strict;comment @ * @;2.3date 96.02.04.23.24.43; author tsurace; state Release;branches;next 2.2;2.2date 95.10.27.20.02.39; author tsurace; state Beta;branches;next 2.1;2.1date 95.10.24.15.46.14; author tsurace; state Exp;branches;next 1.1;1.1date 95.10.12.21.37.13; author tsurace; state Beta;branches;next ;desc@Window management routines.@2.3log@Removed some optimizations that were causing problems.Added some somments.(Note: command-line editor is still partially broken.)@text@/* window.c - Handle I/O to terminal */
/* $Id: window.c 2.2 1995/10/27 20:02:39 tsurace Beta tsurace $ */
#include "vt.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#ifdef __WIN32__
# include "win32/replace.h" /* user i/o routines */
#else /* __WIN32__ */
# include <sys/ioctl.h>
#endif /* __WIN32__ */
#ifdef USE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifdef hpux
#include <termio.h>
#else /* not HP-UX */
#ifdef SYSVTTY
#include <termio.h>
#else /* not SYSVTTY */
#ifdef __WIN32__
#else /* not __WIN32__, probably BSD */
# include <sgtty.h>
#endif
#endif
#endif
#ifdef PROTOTYPES
#ifdef TERMCAP
static void chrpt(int, int);
static void get_ospeed(void);
static void output_one(int);
static void getccap(char *, char *);
static void tp(char *, int);
#endif /* TERMCAP */
static void cap_formatted(char *, int, int);
static void clear_end(void);
static void clear_space(int, int);
static void move_left(int, int);
static void init_window(Unode *, int, int);
static void mark(Unode *, int);
static void draw_prompt(void);
static void clear_input_window(void);
static void chrpt(int c, int num);
void draw_Divider(Unode *win);
#else /* not PROTOTYPES */
#ifdef TERMCAP
static void get_ospeed(), output_one(), getccap(), tp();
#endif /* TERMCAP */
static void chrpt(), cap_formatted(), clear_end(), clear_space(), move_left();
static void init_window(), mark(), draw_prompt(), clear_input_window();
#endif /* not PROTOTYPES */
extern int errno;
extern char *sys_errlist[];
/* Global variables and externs for the terminal routines */
/* The termcap library has no length-checking facilities. We use 32
** bytes for a string that's not pre-compiled with tputs(), and 64
** bytes for one that is. This is somewhat kludgy, but then, so are
** the termcap routines. */
static char s_cmove[32]; /* Move cursor */
static char s_scroll[32]; /* Set scroll area */
static char s_scr_rev[32]; /* Scroll region reverse */
char s_clrscr[64]; /* Clear screen */
char s_clreol[64]; /* Clear to end of line */
char s_bold_on[64]; /* Turn boldface on */
char s_bold_off[64]; /* Turn boldface off */
#ifdef HARDCODE
#define HC_CMOVE "\033[%d;%dH"
#define HC_SCROLL "\033[%d;%dr"
#define HC_SCR_REV "\033M"
#define HC_CLRSCR "\033[2J"
#define HC_CLREOL "\033[K"
#define HC_BOLD_ON "\033[1m"
#define HC_BOLD_OFF "\033[m"
#define cap_normal(x, y) Bwritea(x)
#endif
#define HC_ROWS 24
#define HC_COLS 80
int rows = 0, cols = 0; /* Screen size */
static int scr_top = -1, scr_bot = -1; /* Current scroll area */
#ifdef TERMCAP
static char *cptr;
extern char *tgetstr(), *tgoto();
#ifndef AIX
extern short ospeed;
#endif /* not AIX */
#define cap_normal(x, y) tp(x, y)
#endif /* TERMCAP */
/* Global variables for windowing routines */
#define CURS_INPUT 0
#define CURS_WINDOW 1
#define CURS_ELSEWHERE 2
Unode win_ring; /* Dummy node in windows ring */
Unode *active_win; /* Keyboard text is sent here */
Unode *cur_win = NULL; /* Where text is being processed */
int curs_loc = CURS_ELSEWHERE; /* General idea of where cursor is */
static Unode *curs_win; /* More info for CURS_WINDOW pos */
extern Unode *cur_rmt;
static String outbuf = { { "", 0 }, 0 };/* Output buffering */
#define Die(s) if (1) { puts(s); exit(1); } else
#define Bwrite(cstr) s_cat(&outbuf, cstr)
#define Bwritea(s) s_acat(&outbuf, s)
#define Bwriteal(s, l) s_cat(&outbuf, cstr_sl(s, l))
#define Bwritem(s, y, z) Bwriteal(s, min(y, z))
#define Bputch(c) s_add(&outbuf, c)
#define Bflush if (1) { vtwrite(outbuf.c); s_term(&outbuf, 0); } else
#define BputEOLN() s_add(&outbuf, '\n')
void bflushfunc() { Bflush; }
/* Global variables for input routines */
int icol; /* Column of cursor on bottom line */
char *prompt; /* Text of prompt */
int plen = 0; /* Length of prompt */
int vtc_mode = 0; /* Flag: input window in VTC mode */
extern String kbuf;
extern int kpos;
static int echo_mode = 1;
static int ign_echo_mode = 0;
#define Divider (win_ring.prev->Wbot + 1)
#define Margin (cols - 1)
#define Round(x, y) ((x) - (x) % (y))
#define Klen (kbuf.c.l)
#define Kptr (kbuf.c.s)
#define Oplen (vtc_mode ? 0 : plen)
# define Iclear_end clear_end()
# define Iclear_space(top,bot) clear_space(top,rows-(bot))
# define Icmove(x, y) cmove((x),rows-(y)) // Y is rows up from the bottom
# define Imove_left(count, x) move_left((count), (x))
# define Isize (rows - Itop)
# define Itop (Divider + 1)
# define Iscr_rev if (1) { \
if (Isize > 1) { scroll(Itop, rows - 1); scr_rev(1); } \
else { cmove(0, rows - 1); Bwritea(s_clreol); } \
} else
# define Iscr_fwd if (1) { \
if (Isize > 1) { scroll(Itop, rows - 1); scr_fwd(1); } \
else { cmove(0, rows - 1); Bwritea(s_clreol); } \
} else
# define IBwrite Bwrite
# define IBwritea Bwritea
# define IBwriteal Bwriteal
# define IBwritem Bwritem
# define IBputch Bputch
# define IBputEOLN InWin_puts("\n")
# define IBflush Bflush
/* Low-level I/O */
void vtwrite(cstr)
Cstr cstr;
{
int written;
#ifdef __WIN32__
/* Send output to "console" window */
WriteString(cstr.s, cstr.l);
#else
while (cstr.l > 0) {
written = write(1, cstr.s, cstr.l);
if (written == -1) {
if (errno != EWOULDBLOCK && errno != EINTR) {
perror("write");
vterror("Write failed in vtwrite()");
}
written = 0;
}
cstr = cstr_sl(cstr.s + written, cstr.l - written);
if (cstr.l)
sleep(1);
}
#endif /* __WIN32__ */
}
static void chrpt(c, num)
int c, num;
{
while (num-- > 0)
Bputch(c);
}
#ifdef __WIN32__
/* getch() is in replace.cpp */
#else /* not __WIN32__ */
int getch()
{
char c;
int rs;
while ((rs = read(0, &c, 1)) <= 0) {
if (rs < 0 && errno != EINTR) {
perror("read");
vterror("Read failed in getch()");
}
}
return c;
}
#endif /* __WIN32__ */
void tty_mode(state)
int state;
{
char * ign_teln_echo;
#ifdef hpux
struct termio blob;
if (ioctl(0, TCGETA, &blob) == -1) {
perror("TCGETA ioctl()");
exit(1);
}
if (state) {
blob.c_lflag &= ~ECHO;
blob.c_lflag &= ~ECHOE;
blob.c_lflag &= ~ICANON;
blob.c_cc[VMIN] = 0;
blob.c_cc[VTIME] = 0;
} else {
blob.c_lflag |= ECHO;
blob.c_lflag |= ECHOE;
blob.c_lflag |= ICANON;
}
ioctl(0, TCSETAF, &blob);
#else /* Not HP-UX */
#ifdef SYSVTTY
struct termio blob;
static struct termio old_tty_state;
static int first = 1;
if (first) {
ioctl(0, TCGETA, &old_tty_state);
first = 0;
}
if (state) {
ioctl(0, TCGETA, &blob);
blob.c_cc[VMIN] = 0;
blob.c_cc[VTIME] = 0;
blob.c_iflag = IGNBRK | IGNPAR | ICRNL;
blob.c_oflag = OPOST | ONLCR;
blob.c_lflag = ISIG;
ioctl(0, TCSETA, &blob);
} else if (!first)
ioctl(0, TCSETA, &old_tty_state);
#else
#ifdef __WIN32__
/* If state != 0, disable echo to screen and
ctrl-c, otherwise enable it */
#else /* BSD */
struct sgttyb blob;
if (ioctl(0, TIOCGETP, &blob) == -1) {
perror("TIOCGETP ioctl()");
exit(1);
}
blob.sg_flags |= state ? CBREAK : ECHO;
blob.sg_flags &= state ? ~ECHO : ~CBREAK;
ioctl(0, TIOCSETP, &blob);
#endif
#endif
#endif
/* Flag to ignore telnet echo_on, echo_off commands */
ign_teln_echo = getenv("VT_IGN_ECHO");
if(ign_teln_echo && !strcmp(ign_teln_echo,"YES") )
ign_echo_mode = 1;
}
/* Terminal routines */
#ifdef TERMCAP
static void get_ospeed()
{
#ifndef hpux
#ifndef AIX
#ifndef linux
struct sgttyb sgttyb;
ioctl(0, TIOCGETP, &sgttyb);
ospeed = sgttyb.sg_ospeed;
#endif /* linux */
#endif
#endif
}
static void output_one(c)
int c;
{
*cptr++ = c;
}
static void gettcap(dest, cap)
char *dest, *cap;
{
char buffer[256];
if (!tgetstr(cap, &dest))
{
sprintf(buffer, "Termcap cannot find %s",cap);
Die(buffer);
};
}
static void getccap(dest, cap)
char *dest, *cap;
{
char temp[64];
gettcap(temp, cap);
cptr = dest;
tputs(temp, 1, output_one);
*cptr = '\0';
}
#endif /* TERMCAP */
void init_term()
{
#ifdef HARDCODE
strcpy(s_cmove , HC_CMOVE );
strcpy(s_scroll , HC_SCROLL );
strcpy(s_scr_rev , HC_SCR_REV );
strcpy(s_clrscr , HC_CLRSCR );
strcpy(s_clreol , HC_CLREOL );
strcpy(s_bold_on , HC_BOLD_ON );
strcpy(s_bold_off , HC_BOLD_OFF);
rows = HC_ROWS;
cols = HC_COLS;
#else /* HARDCODE not defined */
char tinfo[1024], *termname, *bon, *boff;
bon = getenv("VTBOLDON");
if (!bon)
bon = "so";
boff = getenv("VTBOLDOFF");
if (!boff)
boff = "se";
termname = getenv("TERM");
if (!termname)
Die("TERM not set");
if (tgetent(tinfo, termname) != 1)
Die("Terminal type not defined.");
rows = tgetnum("li");
if (rows == -1)
rows = HC_ROWS;
cols = tgetnum("co");
if (cols == -1)
cols = HC_COLS;
get_ospeed();
gettcap(s_cmove , "cm");
gettcap(s_scroll , "cs");
gettcap(s_scr_rev , "sr");
getccap(s_clrscr , "cl");
getccap(s_clreol , "ce");
getccap(s_bold_on , bon);
getccap(s_bold_off , boff);
#endif /* HARDCODE not defined */
#ifdef TIOCGWINSZ
{
struct winsize size;
ioctl(0, TIOCGWINSZ, &size);
if (size.ws_row && size.ws_col) {
rows = size.ws_row;
cols = size.ws_col;
}
}
#else /* TIOCGWINSZ */
#ifdef __WIN32__
rows = 35; /* Default size */
cols = 80;
#endif /* __WIN32__ */
#endif /* TIOCGWINSZ */
prompt = vtstrdup("");
}
#ifdef TERMCAP
static void bfuncputch(c) int c; { s_fadd(&outbuf, c); }
static void tp(s, affcnt)
char *s;
int affcnt;
{
tputs(s, affcnt, bfuncputch);
s_nt(&outbuf);
}
#endif
static void cap_formatted(cbuf, arg1, arg2)
char *cbuf;
int arg1, arg2;
{
#ifdef HARDCODE
static char buffer[24];
sprintf(buffer, cbuf, arg2 + 1, arg1 + 1);
Bwritea(buffer);
#else
tp(tgoto(cbuf, arg1, arg2), 1);
#endif
}
void cmove(col, row)
int col, row;
{
assert(col < cols); /* col out of range */
assert(col >= 0);
assert(row < rows); /* row out of range */
assert(row >= 0);
cap_formatted(s_cmove, col, row);
}
/* Set the current scroll area */
void scroll(top, bottom)
int top, bottom;
{
if (scr_top == top && scr_bot == bottom)
return;
cap_formatted(s_scroll, bottom, top);
scr_top = top;
scr_bot = bottom;
}
/* scroll the current area forward */
void scr_fwd(num)
int num;
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -