sldisply.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,241 行 · 第 1/4 页
C
2,241 行
#define TGETNUM tgetnum
#define TGETFLAG tgetflag
#endif
static char *my_tgetstr(char *what, char **p)
{
register char *w, *w1;
char *wsave;
what = tgetstr(what, p);
if (what != NULL)
{
/* Check for AIX brain-damage */
if (*what == '@')
return NULL;
/* lose pad info --- with today's technology, term is a loser if
it is really needed */
while ((*what == '.') ||
((*what >= '0') && (*what <= '9'))) what++;
if (*what == '*') what++;
/* lose terminfo padding--- looks like $<...> */
w = what;
while (*w) if ((*w++ == '$') && (*w == '<'))
{
w1 = w - 1;
while (*w && (*w != '>')) w++;
if (*w == 0) break;
w++;
wsave = w1;
while ((*w1++ = *w++) != 0);
w = wsave;
}
if (*what == 0) what = NULL;
}
return(what);
}
char *SLtt_tgetstr (char *s)
{
#ifdef USE_TERMCAP
static
#endif
char *p = Tstr_Buf;
return my_tgetstr (s, &p);
}
int SLtt_tgetnum (char *s)
{
return TGETNUM (s);
}
int SLtt_tgetflag (char *s)
{
return TGETFLAG (s);
}
static int Vt100_Like = 0;
void SLtt_get_terminfo (void)
{
char *term, *t, ch;
int is_xterm;
int almost_vtxxx;
get_color_info ();
if (NULL == (term = (char *) getenv("TERM")))
{
SLang_exit_error("TERM environment variable needs set.");
}
Linux_Console = (!strncmp (term, "linux", 5)
#ifdef linux
|| !strncmp(term, "con", 3)
#endif
);
t = term;
if (strcmp(t, "vt52") && (*t++ == 'v') && (*t++ == 't')
&& (ch = *t, (ch >= '1') && (ch <= '9'))) Vt100_Like = 1;
is_xterm = !strncmp (term, "xterm", 5);
almost_vtxxx = (Vt100_Like
|| Linux_Console
|| is_xterm
|| !strcmp (term, "screen"));
#ifndef USE_TERMCAP
if (NULL == (Tbuf = tgetent (term)))
{
char err_buf[512];
if (almost_vtxxx) /* Special cases. */
{
int vt102 = 1;
if (!strcmp (term, "vt100")) vt102 = 0;
SLtt_set_term_vtxxx (&vt102);
return;
}
sprintf (err_buf, "Unknown terminal: %s\n\
Check the TERM environment variable.\n\
Also make sure that the terminal is defined in the terminfo database.\n\
Alternatively, set the TERMCAP environment variable to the desired\n\
termcap entry.", term);
SLang_exit_error(err_buf);
}
Tstr_Buf = Tbuf;
#else /* USE_TERMCAP */
if (1 != tgetent(Tbuf, term)) SLang_exit_error("Unknown terminal.");
#endif /* NOT USE_TERMCAP */
if ((NULL == (Cls_Str = SLtt_tgetstr("cl")))
|| (NULL == (Curs_Pos_Str = SLtt_tgetstr("cm"))))
{
SLang_exit_error("Terminal not powerful enough for SLang.");
}
if ((NULL == (Ins_Mode_Str = SLtt_tgetstr("im")))
|| ( NULL == (Eins_Mode_Str = SLtt_tgetstr("ei")))
|| ( NULL == (Del_Char_Str = SLtt_tgetstr("dc"))))
SLtt_Term_Cannot_Insert = 1;
Visible_Bell_Str = SLtt_tgetstr ("vb");
Curs_Up_Str = SLtt_tgetstr ("up");
Rev_Scroll_Str = SLtt_tgetstr("sr");
Del_N_Lines_Str = SLtt_tgetstr("DL");
Add_N_Lines_Str = SLtt_tgetstr("AL");
/* Actually these are used to initialize terminals that use cursor
* addressing. Hard to believe.
*/
Term_Init_Str = SLtt_tgetstr ("ti");
Term_Reset_Str = SLtt_tgetstr ("te");
/* If I do this for vtxxx terminals, arrow keys start sending ESC O A,
* which I do not want. This is mainly for HP terminals.
*/
if ((almost_vtxxx == 0) || SLtt_Force_Keypad_Init)
{
Keypad_Init_Str = SLtt_tgetstr ("ks");
Keypad_Reset_Str = SLtt_tgetstr ("ke");
}
/* Make up for defective termcap/terminfo databases */
if ((Vt100_Like && (term[2] != '1'))
|| Linux_Console
|| is_xterm
)
{
if (Del_N_Lines_Str == NULL) Del_N_Lines_Str = "\033[%dM";
if (Add_N_Lines_Str == NULL) Add_N_Lines_Str = "\033[%dL";
}
Scroll_R_Str = SLtt_tgetstr("cs");
SLtt_get_screen_size ();
if ((Scroll_R_Str == NULL)
|| (((NULL == Del_N_Lines_Str) || (NULL == Add_N_Lines_Str))
&& (NULL == Rev_Scroll_Str)))
{
if (is_xterm
|| Linux_Console
)
{
/* Defective termcap mode!!!! */
SLtt_set_term_vtxxx (NULL);
}
else SLtt_Term_Cannot_Scroll = 1;
}
Del_Eol_Str = SLtt_tgetstr("ce");
Rev_Vid_Str = SLtt_tgetstr("mr");
if (Rev_Vid_Str == NULL) Rev_Vid_Str = SLtt_tgetstr("so");
Bold_Vid_Str = SLtt_tgetstr("md");
/* Although xterm cannot blink, it does display the blinking characters
* as bold ones. Some Rxvt will display the background as high intensity.
*/
if ((NULL == (Blink_Vid_Str = SLtt_tgetstr("mb")))
&& is_xterm)
Blink_Vid_Str = "\033[5m";
UnderLine_Vid_Str = SLtt_tgetstr("us");
Start_Alt_Chars_Str = SLtt_tgetstr ("as"); /* smacs */
End_Alt_Chars_Str = SLtt_tgetstr ("ae"); /* rmacs */
Enable_Alt_Char_Set = SLtt_tgetstr ("eA"); /* enacs */
SLtt_Graphics_Char_Pairs = SLtt_tgetstr ("ac");
#ifndef NCURSES_BRAIN_DAMAGE_CONTROL
# define NCURSES_BRAIN_DAMAGE_CONTROL 0
#endif
#if NCURSES_BRAIN_DAMAGE_CONTROL
if (Linux_Console)
{
# if 0
char *lgcp = "l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\053o\176s\137`\004a\260f\370g\361~\011,\020+\021.\031-\030h\261i\0250\333";
SLtt_Graphics_Char_Pairs = lgcp;
Start_Alt_Chars_Str = "\033(B\033)U\016";
End_Alt_Chars_Str = "\033(B\033)0\017";
Enable_Alt_Char_Set = NULL;
# else
char *lgcp = "`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o\302q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~";
SLtt_Graphics_Char_Pairs = lgcp;
Start_Alt_Chars_Str = "\033[11m";
End_Alt_Chars_Str = "\033[10m";
Enable_Alt_Char_Set = NULL;
# endif
}
#endif
if (NULL == SLtt_Graphics_Char_Pairs)
{
/* make up for defective termcap/terminfo */
if (Vt100_Like)
{
Start_Alt_Chars_Str = "\016";
End_Alt_Chars_Str = "\017";
Enable_Alt_Char_Set = "\033)0";
}
}
/* aixterm added by willi */
if (is_xterm || !strncmp (term, "aixterm", 7))
{
Start_Alt_Chars_Str = "\016";
End_Alt_Chars_Str = "\017";
Enable_Alt_Char_Set = "\033(B\033)0";
}
if ((SLtt_Graphics_Char_Pairs == NULL) &&
((Start_Alt_Chars_Str == NULL) || (End_Alt_Chars_Str == NULL)))
{
SLtt_Has_Alt_Charset = 0;
Enable_Alt_Char_Set = NULL;
}
else SLtt_Has_Alt_Charset = 1;
/* status line capabilities */
if ((SLtt_Has_Status_Line == -1)
&& (0 != (SLtt_Has_Status_Line = TGETFLAG ("hs"))))
{
Disable_Status_line_Str = SLtt_tgetstr ("ds");
Return_From_Status_Line_Str = SLtt_tgetstr ("fs");
Goto_Status_Line_Str = SLtt_tgetstr ("ts");
Status_Line_Esc_Ok = TGETFLAG("es");
Num_Status_Line_Columns = TGETNUM("ws");
if (Num_Status_Line_Columns < 0) Num_Status_Line_Columns = 0;
}
if (NULL == (Norm_Vid_Str = SLtt_tgetstr("me")))
{
Norm_Vid_Str = SLtt_tgetstr("se");
}
Cursor_Invisible_Str = SLtt_tgetstr("vi");
Cursor_Visible_Str = SLtt_tgetstr("ve");
Curs_F_Str = SLtt_tgetstr("RI");
#if 0
if (NULL != Curs_F_Str)
{
Len_Curs_F_Str = strlen(Curs_F_Str);
}
else Len_Curs_F_Str = strlen(Curs_Pos_Str);
#endif
Automatic_Margins = TGETFLAG ("am");
/* No_Move_In_Standout = !TGETFLAG ("ms"); */
#ifdef HP_GLITCH_CODE
Has_HP_Glitch = TGETFLAG ("xs");
#else
Worthless_Highlight = TGETFLAG ("xs");
#endif
if (Worthless_Highlight == 0)
{ /* Magic cookie glitch */
Worthless_Highlight = (TGETNUM ("sg") > 0);
}
if (Worthless_Highlight)
SLtt_Has_Alt_Charset = 0;
/* Check for color information in the termcap. A program should not
* rely on this information being accurate.
*/
if (SLtt_Use_Ansi_Colors == 0)
{
Reset_Color_String = SLtt_tgetstr ("op");
SLtt_Use_Ansi_Colors = ((NULL != Reset_Color_String)
|| (NULL != SLtt_tgetstr ("Sf"))
|| (NULL != SLtt_tgetstr ("Sb"))
|| (NULL != SLtt_tgetstr ("AF"))
|| (NULL != SLtt_tgetstr ("AB"))
|| (-1 != SLtt_tgetnum ("Co"))
|| (-1 != SLtt_tgetnum ("pa")));
}
#if defined(__QNX__) && defined(QNX_QANSI_SLANG_COMPAT_ACS)
/*
* Override the alt-char-set handling string in case of a
* QNX/qansi terminal: use the "old style" strings in order
* to be compatible with S-Lang without the SLTT_TRANSP_ACS_PATCH
* code...
*/
if (SLtt_Has_Alt_Charset &&
strncmp(term, "qansi", 5) == 0 &&
Start_Alt_Chars_Str[0] != '\016')
{
Start_Alt_Chars_Str = "\016"; /* smacs/as (^N) */
End_Alt_Chars_Str = "\017"; /* rmacs/ae (^O) */
SLtt_Graphics_Char_Pairs = /* acsc/ac */
"``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~O\141";
/*
* it would be required to modify the sgr/sa entry also, if it
* would be used (->embedded as/ae sequences)...
*/
}
#endif /* __QNX__ && QNX_QANSI_SLANG_COMPAT_ACS */
}
#endif
/* Unix */
/* specific to vtxxx only */
void SLtt_enable_cursor_keys (void)
{
#ifdef __unix__
if (Vt100_Like)
#endif
SLtt_write_string("\033=\033[?1l");
}
#ifdef VMS
void SLtt_get_terminfo ()
{
int zero = 0;
get_color_info ();
SLtt_set_term_vtxxx(&zero);
Start_Alt_Chars_Str = "\016";
End_Alt_Chars_Str = "\017";
SLtt_Has_Alt_Charset = 1;
SLtt_Graphics_Char_Pairs = "aaffgghhjjkkllmmnnooqqssttuuvvwwxx";
Enable_Alt_Char_Set = "\033(B\033)0";
SLtt_get_screen_size ();
}
#endif
/* This sets term for vt102 terminals it parameter vt100 is 0. If vt100
* is non-zero, set terminal appropriate for a only vt100
* (no add line capability). */
void SLtt_set_term_vtxxx(int *vt100)
{
Norm_Vid_Str = "\033[m";
Scroll_R_Str = "\033[%i%d;%dr";
Cls_Str = "\033[2J\033[H";
Rev_Vid_Str = "\033[7m";
Bold_Vid_Str = "\033[1m";
Blink_Vid_Str = "\033[5m";
UnderLine_Vid_Str = "\033[4m";
Del_Eol_Str = "\033[K";
Rev_Scroll_Str = "\033M";
Curs_F_Str = "\033[%dC";
/* Len_Curs_F_Str = 5; */
Curs_Pos_Str = "\033[%i%d;%dH";
if ((vt100 == NULL) || (*vt100 == 0))
{
Ins_Mode_Str = "\033[4h";
Eins_Mode_Str = "\033[4l";
Del_Char_Str = "\033[P";
Del_N_Lines_Str = "\033[%dM";
Add_N_Lines_Str = "\033[%dL";
SLtt_Term_Cannot_Insert = 0;
}
else
{
Del_N_Lines_Str = NULL;
Add_N_Lines_Str = NULL;
SLtt_Term_Cannot_Insert = 1;
}
SLtt_Term_Cannot_Scroll = 0;
/* No_Move_In_Standout = 0; */
}
void SLtt_init_video (void)
{
/* send_string_to_term("\033[?6h"); */
/* relative origin mode */
SLtt_write_string (Term_Init_Str);
SLtt_write_string (Keypad_Init_Str);
SLtt_reset_scroll_region();
SLtt_end_insert();
SLtt_write_string (Enable_Alt_Char_Set);
Video_Initialized = 1;
}
void SLtt_reset_video (void)
{
SLtt_goto_rc (SLtt_Screen_Rows - 1, 0);
Cursor_Set = 0;
SLtt_normal_video (); /* MSKermit requires this */
SLtt_write_string(Norm_Vid_Str);
Current_Fgbg = 0xFFFFFFFFU;
SLtt_set_alt_char_set (0);
if (SLtt_Use_Ansi_Colors)
{
if (Reset_Color_String == NULL)
{
SLtt_Char_Type attr;
if (-1 != make_color_fgbg (NULL, NULL, &attr))
write_attributes (attr);
else SLtt_write_string ("\033[0m\033[m");
}
else SLtt_write_string (Reset_Color_String);
Current_Fgbg = 0xFFFFFFFFU;
}
SLtt_erase_line ();
SLtt_write_string (Keypad_Reset_Str);
SLtt_write_string (Term_Reset_Str);
SLtt_flush_output ();
Video_Initialized = 0;
}
void SLtt_bold_video (void)
{
SLtt_write_string (Bold_Vid_Str);
}
int SLtt_set_mouse_mode (int mode, int force)
{
char *term;
if (force == 0)
{
if (NULL == (term = (char *) getenv("TERM"))) return -1;
if (strncmp ("xterm", term, 5))
return -1;
}
if (mode)
SLtt_write_string ("\033[?9h");
else
SLtt_write_string ("\033[?9l");
return 0;
}
void SLtt_disable_status_line (void)
{
if (SLtt_Has_Status_Line > 0)
SLtt_write_string (Disable_Status_line_Str);
}
int SLtt_write_to_status_line (char *s, int col)
{
if ((SLtt_Has_Status_Line <= 0)
|| (Goto_Status_Line_Str == NULL)
|| (Return_From_Status_Line_Str == NULL))
return -1;
tt_printf (Goto_Status_Line_Str, col, 0);
SLtt_write_string (s);
SLtt_write_string (Return_From_Status_Line_Str);
return 0;
}
void SLtt_get_screen_size (void)
{
#ifdef VMS
int status, code;
unsigned short chan;
$DESCRIPTOR(dev_dsc, "SYS$INPUT:");
#endif
#ifdef __os2__
VIOMODEINFO vioModeInfo;
#endif
int r = 0, c = 0;
#if defined(TIOCGWINSZ) && !defined(SCO_FLAVOR)
struct winsize wind_struct;
do
{
if ((ioctl(1,TIOCGWINSZ,&wind_struct) == 0)
|| (ioctl(0, TIOCGWINSZ, &wind_struct) == 0)
|| (ioctl(2, TIOCGWINSZ, &wind_struct) == 0))
{
c = (int) wind_struct.ws_col;
r = (int) wind_struct.ws_row;
break;
}
}
while (errno == EINTR);
#endif
#ifdef VMS
status = sys$assign(&dev_dsc,&chan,0,0,0);
if (status & 1)
{
code = DVI$_DEVBUFSIZ;
status = lib$getdvi(&code, &chan,0, &c, 0,0);
if (!(status & 1))
c = 80;
code = DVI$_TT_PAGE;
status = lib$getdvi(&code, &chan,0, &r, 0,0);
if (!(status & 1))
r = 24;
sys$dassgn(chan);
}
#endif
#ifdef __os2__
vioModeInfo.cb = sizeof(vioModeInfo);
VioGetMode (&vioModeInfo, 0);
c = vioModeInfo.col;
r = vioModeInfo.row;
#endif
if (r <= 0)
{
char *s = getenv ("LINES");
if (s != NULL) r = atoi (s);
}
if (c <= 0)
{
char *s = getenv ("COLUMNS");
if (s != NULL) c = atoi (s);
}
if ((r <= 0) || (r > 200)) r = 24;
if ((c <= 0) || (c > 250)) c = 80;
SLtt_Screen_Rows = r;
SLtt_Screen_Cols = c;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?