📄 sldisply.c
字号:
if (ch == '\n') ch++; *b++ = ch; } break; /* Binary operators */ case '-': case '*': case '/': case 'm': case '&': case '|': case '^': case '=': case '>': case '<': case 'A': case 'O': z1 = STACK_POP; z = STACK_POP; switch (ch) { case '-': z = (z - z1); break; case '*': z = (z * z1); break; case '/': z = (z / z1); break; case 'm': z = (z % z1); break; case '&': z = (z & z1); break; case '|': z = (z | z1); break; case '^': z = (z ^ z1); break; case '=': z = (z == z1); break; case '>': z = (z > z1); break; case '<': z = (z < z1); break; case 'A': z = (z && z1); break; case 'O': z = (z || z1); break; } stack [stack_len++] = z; break; /* unary */ case '!': z = STACK_POP; stack [stack_len++] = !z; break; case '~': z = STACK_POP; stack [stack_len++] = ~z; break; case 'r': /* termcap -- swap parameters */ z = stack [0]; stack [0] = stack [1]; stack [1] = z; break; case '.': /* termcap */ case 'c': ch = (unsigned char) STACK_POP; if (ch == '\n') ch++; *b++ = ch; break; case 'g': if (fmt == fmt_max) break; ch = *fmt++; if ((ch >= 'a') && (ch <= 'z')) stack [stack_len++] = variables [ch - 'a']; break; case 'P': if (fmt == fmt_max) break; ch = *fmt++; if ((ch >= 'a') && (ch <= 'z')) variables [ch - 'a'] = STACK_POP; break; /* If then else parsing. Actually, this is rather easy. The * key is to notice that 'then' does all the work. 'if' simply * there to indicate the start of a test and endif indicates * the end of tests. If 'else' is seen, then skip to * endif. */ case '?': /* if */ case ';': /* endif */ break; case 't': /* then */ z = STACK_POP; if (z != 0) break; /* good. Continue parsing. */ /* z == 0 and test has failed. So, skip past this entire if * expression to the matching else or matching endif. */ /* drop */ case 'e': /* else */ parse_level = 0; while (fmt < fmt_max) { unsigned char ch1; ch1 = *fmt++; if ((ch1 != '%') || (fmt == fmt_max)) continue; ch1 = *fmt++; if (ch1 == '?') parse_level++; /* new if */ else if (ch1 == 'e') { if ((ch != 'e') && (parse_level == 0)) break; } else if (ch1 == ';') { if (parse_level == 0) break; parse_level--; } } break; } } *b = 0; return (unsigned int) (b - (unsigned char *) buf);}static void tt_printf(char *fmt, int x, int y){ char buf[1024]; unsigned int n; if (fmt == NULL) return; n = tt_sprintf(buf, fmt, x, y); tt_write(buf, n);}void SLtt_set_scroll_region (int r1, int r2){ Scroll_r1 = r1; Scroll_r2 = r2; tt_printf (Scroll_R_Str, Scroll_r1, Scroll_r2); Cursor_Set = 0;}void SLtt_reset_scroll_region (void){ SLtt_set_scroll_region(0, SLtt_Screen_Rows - 1);}int SLtt_set_cursor_visibility (int show){ if ((Cursor_Visible_Str == NULL) || (Cursor_Invisible_Str == NULL)) return -1; tt_write_string (show ? Cursor_Visible_Str : Cursor_Invisible_Str); return 0;}/* the goto_rc function moves to row relative to scrolling region */void SLtt_goto_rc(int r, int c){ char *s = NULL; int n; char buf[6]; if ((c < 0) || (r < 0)) { Cursor_Set = 0; return; } /* if (No_Move_In_Standout && Current_Fgbg) SLtt_normal_video (); */ r += Scroll_r1; if ((Cursor_Set > 0) || ((Cursor_Set < 0) && !Automatic_Margins)) { n = r - Cursor_r; if ((n == -1) && (Cursor_Set > 0) && (Cursor_c == c) && (Curs_Up_Str != NULL)) { s = Curs_Up_Str; } else if ((n >= 0) && (n <= 4)) { if ((n == 0) && (Cursor_Set == 1) && ((c > 1) || (c == Cursor_c))) { if (Cursor_c == c) return; if (Cursor_c == c + 1) { s = buf; *s++ = '\b'; *s = 0; s = buf; } } else if (c == 0) { s = buf; if ((Cursor_Set != 1) || (Cursor_c != 0)) *s++ = '\r'; while (n--) *s++ = '\n';#ifdef VMS /* Need to add this after \n to start a new record. Sheesh. */ *s++ = '\r';#endif *s = 0; s = buf; } /* Will fail on VMS */#ifndef VMS else if (SLtt_Newline_Ok && (Cursor_Set == 1) && (Cursor_c >= c) && (c + 3 > Cursor_c)) { s = buf; while (n--) *s++ = '\n'; n = Cursor_c - c; while (n--) *s++ = '\b'; *s = 0; s = buf; }#endif } } if (s != NULL) tt_write_string(s); else tt_printf(Curs_Pos_Str, r, c); Cursor_c = c; Cursor_r = r; Cursor_Set = 1;}void SLtt_begin_insert (void){ tt_write_string(Ins_Mode_Str);}void SLtt_end_insert (void){ tt_write_string(Eins_Mode_Str);}void SLtt_delete_char (void){ SLtt_normal_video (); tt_write_string(Del_Char_Str);}void SLtt_erase_line (void){ tt_write_string("\r"); Cursor_Set = 1; Cursor_c = 0; SLtt_del_eol(); /* Put the cursor back at the beginning of the line */ tt_write_string("\r"); Cursor_Set = 1; Cursor_c = 0;}/* It appears that the Linux console, and most likely others do not * like scrolling regions that consist of one line. So I have to * resort to this stupidity to make up for that stupidity. */static void delete_line_in_scroll_region (void){ SLtt_goto_rc (Cursor_r - Scroll_r1, 0); SLtt_del_eol ();}void SLtt_delete_nlines (int n){ int r1, curs; char buf[132]; if (n <= 0) return; SLtt_normal_video (); if (Scroll_r1 == Scroll_r2) { delete_line_in_scroll_region (); return; } if (Del_N_Lines_Str != NULL) tt_printf(Del_N_Lines_Str,n, 0); else /* get a new terminal */ { r1 = Scroll_r1; curs = Cursor_r; SLtt_set_scroll_region(curs, Scroll_r2); SLtt_goto_rc(Scroll_r2 - Scroll_r1, 0); SLMEMSET(buf, '\n', (unsigned int) n); tt_write(buf, (unsigned int) n); /* while (n--) tt_putchar('\n'); */ SLtt_set_scroll_region(r1, Scroll_r2); SLtt_goto_rc(curs, 0); }}void SLtt_cls (void){ /* If the terminal is a color terminal but the user wants black and * white, then make sure that the colors are reset. This appears to be * necessary. */ if ((SLtt_Use_Ansi_Colors == 0) && Is_Color_Terminal) { if (Reset_Color_String != NULL) tt_write_string (Reset_Color_String); else tt_write_string ("\033[0m\033[m"); } SLtt_normal_video(); SLtt_reset_scroll_region (); tt_write_string(Cls_Str);}void SLtt_reverse_index (int n){ if (!n) return; SLtt_normal_video(); if (Scroll_r1 == Scroll_r2) { delete_line_in_scroll_region (); return; } if (Add_N_Lines_Str != NULL) tt_printf(Add_N_Lines_Str,n, 0); else { while(n--) tt_write_string(Rev_Scroll_Str); }}int SLtt_Ignore_Beep = 1;static char *Visible_Bell_Str;void SLtt_beep (void){ if (SLtt_Ignore_Beep & 0x1) SLtt_putchar('\007'); if (SLtt_Ignore_Beep & 0x2) { if (Visible_Bell_Str != NULL) tt_write_string (Visible_Bell_Str);#ifdef __linux__ else if (Linux_Console) { tt_write_string ("\033[?5h"); SLtt_flush_output (); _SLusleep (50000); tt_write_string ("\033[?5l"); }#endif } SLtt_flush_output ();}static void write_string_with_care (char *);static void del_eol (void){#if 0 int c;#endif if ((Del_Eol_Str != NULL) && (Can_Background_Color_Erase || ((Current_Fgbg & ~0xFF) == 0))) { tt_write_string(Del_Eol_Str); return; }#if 0 c = Cursor_c; /* Avoid writing to the lower right corner. If the terminal does not * have Del_Eol_Str, then it probably does not have what it takes to play * games with insert-mode to "push" the desired character into that corner. */ if (Cursor_r + 1 < SLtt_Screen_Rows) c++; while (c < SLtt_Screen_Cols) { tt_write (" ", 1); c++; } Cursor_c = (SLtt_Screen_Cols-1);#else while (Cursor_c < SLtt_Screen_Cols) { write_string_with_care (" "); Cursor_c++; } Cursor_c = SLtt_Screen_Cols - 1; Cursor_Set = 0;#endif}void SLtt_del_eol (void){ if (Current_Fgbg != 0xFFFFFFFFU) SLtt_normal_video (); del_eol ();}typedef SLCONST struct{ char *name; SLtt_Char_Type color;}Color_Def_Type;#define MAX_COLOR_NAMES 17static Color_Def_Type Color_Defs [MAX_COLOR_NAMES] ={ {"black", SLSMG_COLOR_BLACK}, {"red", SLSMG_COLOR_RED}, {"green", SLSMG_COLOR_GREEN}, {"brown", SLSMG_COLOR_BROWN}, {"blue", SLSMG_COLOR_BLUE}, {"magenta", SLSMG_COLOR_MAGENTA}, {"cyan", SLSMG_COLOR_CYAN}, {"lightgray", SLSMG_COLOR_LGRAY}, {"gray", SLSMG_COLOR_GRAY}, {"brightred", SLSMG_COLOR_BRIGHT_RED}, {"brightgreen", SLSMG_COLOR_BRIGHT_GREEN}, {"yellow", SLSMG_COLOR_BRIGHT_BROWN}, {"brightblue", SLSMG_COLOR_BRIGHT_BLUE}, {"brightmagenta", SLSMG_COLOR_BRIGHT_CYAN}, {"brightcyan", SLSMG_COLOR_BRIGHT_MAGENTA}, {"white", SLSMG_COLOR_BRIGHT_WHITE},#define SLSMG_COLOR_DEFAULT 0xFF {"default", SLSMG_COLOR_DEFAULT}};void SLtt_set_mono (int obj, char *what, SLtt_Char_Type mask){ (void) what; if ((obj < 0) || (obj >= JMAX_COLORS)) { return; } Ansi_Color_Map[obj].mono = mask & ATTR_MASK;}static char *check_color_for_digit_form (char *color){ unsigned int i, ich; unsigned char *s = (unsigned char *) color; i = 0; while ((ich = (unsigned int) *s) != 0) { if ((ich < '0') || (ich > '9')) return color; i = i * 10 + (ich - '0'); s++; } if (i < MAX_COLOR_NAMES) color = Color_Defs[i].name; return color;}static int get_default_colors (char **fgp, char **bgp){ static char fg_buf[16], bg_buf[16], *bg, *fg; static int already_parsed; char *p, *pmax; if (already_parsed == -1) return -1; if (already_parsed) { *fgp = fg; *bgp = bg; return 0; } already_parsed = -1; bg = getenv ("COLORFGBG"); if (bg == NULL) { bg = getenv ("DEFAULT_COLORS"); if (bg == NULL) return -1; } p = fg_buf; pmax = p + (sizeof (fg_buf) - 1); while ((*bg != 0) && (*bg != ';')) { if (p < pmax) *p++ = *bg; bg++; } *p = 0; if (*bg) bg++; p = bg_buf; pmax = p + (sizeof (bg_buf) - 1); /* Mark suggested allowing for extra application specific stuff following * the background color. That is what the check for the semi-colon is for. */ while ((*bg != 0) && (*bg != ';')) { if (p < pmax) *p++ = *bg; bg++; } *p = 0; if (!strcmp (fg_buf, "default") || !strcmp(bg_buf, "default")) { *fgp = *bgp = fg = bg = "default"; } else { *fgp = fg = check_color_for_digit_form (fg_buf); *bgp = bg = check_color_for_digit_form (bg_buf); } already_parsed = 1; return 0;}static unsigned char FgBg_Stats[JMAX_COLORS];static int Color_0_Modified = 0;void SLtt_set_color_object (int obj, SLtt_Char_Type attr){ char *cust_esc; if ((obj < 0) || (obj >= JMAX_COLORS)) return; cust_esc = Ansi_Color_Map[obj].custom_esc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -