📄 sldisply.c
字号:
#if SLTT_USE_INSERT_HACK SLsmg_Char_Type insert_hack_prev = 0; SLsmg_Char_Type insert_hack_char = 0; if ((row + 1 == SLtt_Screen_Rows) && (len == SLtt_Screen_Cols) && (len > 1) && (SLtt_Term_Cannot_Insert == 0) && Automatic_Margins) { insert_hack_char = neww[len-1]; if (oldd[len-1] == insert_hack_char) insert_hack_char = 0; else insert_hack_prev = neww[len-2]; }#endif if (len > SLTT_MAX_SCREEN_COLS) len = SLTT_MAX_SCREEN_COLS; q = oldd; p = neww; qmax = oldd + len; pmax = p + len; /* Find out where to begin --- while they match, we are ok */ while (1) { if (q == qmax) return;#if SLANG_HAS_KANJI_SUPPORT if (*p & 0x80) { /* new is kanji */ if ((*q & 0x80) && ((q + 1) < qmax)) { /* old is also kanji */ if (((0xFF & *q) != (0xFF & *p)) || ((0xFF & q[1]) != (0xFF & p[1]))) break; /* both kanji, but not match */ else { /* kanji match ! */ if (!COLOR_EQS(*q, *p)) break; q++; p++; if (!COLOR_EQS(*q, *p)) break; /* really match! */ q++; p++; continue; } } else break; /* old is not kanji */ } else { /* new is not kanji */ if (*q & 0x80) break; /* old is kanji */ }#endif if (!CHAR_EQS(*q, *p)) break; q++; p++; }#ifdef HP_GLITCH_CODE if (Has_HP_Glitch) { SLsmg_Char_Type *qq = q; SLtt_goto_rc (row, (int) (p - neww)); while (qq < qmax) { if (*qq & 0xFF00) { SLtt_normal_video (); SLtt_del_eol (); qmax = q; handle_hp_glitch = 1; break; } qq++; } }#endif /* Find where the last non-blank character on old/new screen is */ space_char = ' '; if (CHAR_EQS(*(pmax-1), ' ')) { /* If we get here, then we can erase to the end of the line to create * the final space. However, this will only work _if_ erasing will * get us the correct color. If the terminal supports BCE, then this * is easy. If it does not, then we can only perform this operation * if the color is known via something like COLORFGBG. For now, * I just will not perform the optimization for such terminals. */ if ((Can_Background_Color_Erase) && SLtt_Use_Ansi_Colors) space_char = *(pmax - 1); while (pmax > p) { pmax--; if (!CHAR_EQS(*pmax, space_char)) { pmax++; break; } } } while (qmax > q) { qmax--; if (!CHAR_EQS(*qmax, space_char)) { qmax++; break; } } last_buffered_match = buf = buffer; /* buffer is empty */#ifdef HP_GLITCH_CODE if (handle_hp_glitch) { while (p < pmax) { *buf++ = *p++; } }#endif#ifdef HP_GLITCH_CODE if (Has_HP_Glitch == 0) {#endif /* Try use use erase to bol if possible */ if ((Del_Bol_Str != NULL) && (CHAR_OF(*neww) == ' ')) { SLsmg_Char_Type *p1; SLsmg_Char_Type blank; p1 = neww; if ((Can_Background_Color_Erase) && SLtt_Use_Ansi_Colors) blank = *p1; /* black+white attributes do not support bce */ else blank = ' '; while ((p1 < pmax) && (CHAR_EQS (*p1, blank))) p1++; /* Is this optimization worth it? Assume Del_Bol_Str is ESC [ 1 K * It costs 4 chars + the space needed to properly position the * cursor, e.g., ESC [ 10;10H. So, it costs at least 13 characters. */ if ((p1 > neww + 13) && (p1 >= p) /* Avoid erasing from the end of the line */ && ((p1 != pmax) || (pmax < neww + len))) { int ofs = (int) (p1 - neww); q = oldd + ofs; p = p1; SLtt_goto_rc (row, ofs - 1); SLtt_reverse_video (COLOR_OF(blank)); tt_write_string (Del_Bol_Str); tt_write (" ", 1); Cursor_c += 1; } else SLtt_goto_rc (row, (int) (p - neww)); } else SLtt_goto_rc (row, (int) (p - neww));#ifdef HP_GLITCH_CODE }#endif /* loop using overwrite then skip algorithm until done */ while (1) { /* while they do not match and we do not hit a space, buffer them up */ n_spaces = 0; while (p < pmax) { if (CHAR_EQS(*q, ' ') && CHAR_EQS(*p, ' ')) { /* If *q is not a space, we would have to overwrite it. * However, if *q is a space, then while *p is also one, * we only need to skip over the blank field. */ space_match = p; p++; q++; while ((p < pmax) && CHAR_EQS(*q, ' ') && CHAR_EQS(*p, ' ')) { p++; q++; } n_spaces = (unsigned int) (p - space_match); break; }#if SLANG_HAS_KANJI_SUPPORT if ((*p & 0x80) && ((p + 1) < pmax)) { /* new is kanji */ if (*q & 0x80) { /* old is also kanji */ if (((0xFF & *q) != (0xFF & *p)) || ((0xFF & q[1]) != (0xFF & p[1]))) { /* both kanji, but not match */ *buf++ = *p++; *buf++ = *p++; q += 2; continue; } else { /* kanji match ? */ if (!COLOR_EQS(*q, *p) || !COLOR_EQS(*(q+1), *(p+1))) { /* code is match, but color is diff */ *buf++ = *p++; *buf++ = *p++; q += 2; continue; } /* really match ! */ break; } } else { /* old is not kanji */ *buf++ = *p++; *buf++ = *p++; q += 2; continue; } } else { /* new is not kanji */ if (*q & 0x80) { /* old is kanji */ *buf++ = *p++; q++; continue; } }#endif if (CHAR_EQS(*q, *p)) break; *buf++ = *p++; q++; } *buf = 0; /* At this point, the buffer contains characters that do not match */ if (buf != buffer) send_attr_str (buffer); buf = buffer; if (n_spaces && ((p < pmax) /* erase to eol will achieve this effect*/ || (space_char != ' ')))/* unless space_char is not a simple space */ { forward_cursor (n_spaces, row); } /* Now we overwrote what we could and cursor is placed at position * of a possible match of new and old. If this is the case, skip * some more. */ /* Note that from here on, the buffer will contain matched characters */#if !SLANG_HAS_KANJI_SUPPORT while ((p < pmax) && CHAR_EQS(*p, *q)) { *buf++ = *p++; q++; }#else /* Kanji */ while (p < pmax) { if ((*p & 0x80) && ((p + 1) < pmax)) { /* new is kanji */ if (*q & 0x80) { /* old is also kanji */ if (((0xFF & *q) == (0xFF & *p)) && ((0xFF & q[1]) == (0xFF & p[1]))) { /* kanji match ? */ if (!COLOR_EQS(*q, *p) || !COLOR_EQS(q[1], p[1])) break; *buf++ = *p++; q++; if (p >= pmax) { *buf++ = 32; p++; break; } else { *buf++ = *p++; q++; continue; } } else break; /* both kanji, but not match */ } else break; /* old is not kanji */ } else { /* new is not kanji */ if (*q & 0x80) break; /* old is kanji */ if (!CHAR_EQS(*q, *p)) break; *buf++ = *p++; q++; } }#endif last_buffered_match = buf; if (p >= pmax) break; /* jump to new position is it is greater than 5 otherwise * let it sit in the buffer and output it later. */ if ((int) (buf - buffer) >= 5) { forward_cursor ((unsigned int) (buf - buffer), row); last_buffered_match = buf = buffer; } } /* At this point we have reached the end of the new string with the * exception of space_chars hanging off the end of it, but we may not have * reached the end of the old string if they did not match. */ /* Here the buffer will consist only of characters that have matched */ if (buf != buffer) { if (q < qmax) { if ((buf == last_buffered_match) && ((int) (buf - buffer) >= 5)) { forward_cursor ((unsigned int) (buf - buffer), row); } else { *buf = 0; send_attr_str (buffer); } } } if (q < qmax) { SLtt_reverse_video (COLOR_OF(space_char)); del_eol (); } #if SLTT_USE_INSERT_HACK else if (insert_hack_char) { SLtt_goto_rc (SLtt_Screen_Rows-1, SLtt_Screen_Cols-2); buffer[0] = insert_hack_char; buffer[1] = 0; send_attr_str (buffer); SLtt_goto_rc (SLtt_Screen_Rows-1, SLtt_Screen_Cols-2); buffer[0] = insert_hack_prev; SLtt_begin_insert (); send_attr_str (buffer); SLtt_end_insert (); }#endif if (Automatic_Margins && (Cursor_c + 1 >= SLtt_Screen_Cols)) Cursor_Set = 0;}static void get_color_info (void){ char *fg, *bg; /* Allow easy mechanism to override inadequate termcap/terminfo files. */ if (SLtt_Use_Ansi_Colors == 0) SLtt_Use_Ansi_Colors = (NULL != getenv ("COLORTERM")); if (SLtt_Use_Ansi_Colors) Is_Color_Terminal = 1;#if SLTT_HAS_NON_BCE_SUPPORT if (Can_Background_Color_Erase == 0) Can_Background_Color_Erase = (NULL != getenv ("COLORTERM_BCE"));#endif if (-1 == get_default_colors (&fg, &bg)) return; /* Check to see if application has already set them. */ if (Color_0_Modified) return; SLtt_set_color (0, NULL, fg, bg); SLtt_set_color (1, NULL, bg, fg);}/* termcap stuff */#ifdef __unix__static int Termcap_Initalized = 0;#ifdef USE_TERMCAP/* Termcap based system */static char Termcap_Buf[4096];static char Termcap_String_Buf[4096];static char *Termcap_String_Ptr;extern char *tgetstr(char *, char **);extern int tgetent(char *, char *);extern int tgetnum(char *);extern int tgetflag(char *);#else/* Terminfo */static SLterminfo_Type *Terminfo;#endif#define TGETFLAG(x) (SLtt_tgetflag(x) > 0)static char *fixup_tgetstr (char *what){ register char *w, *w1; char *wsave; if (what == NULL) return 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 *cap){ char *s; if (Termcap_Initalized == 0) return NULL; #ifdef USE_TERMCAP s = tgetstr (cap, &Termcap_String_Ptr);#else s = _SLtt_tigetstr (Terminfo, cap);#endif /* Do not strip pad info for alternate character set. I need to make * this more general. */ /* FIXME: Priority=low; */ if (0 == strcmp (cap, "ac")) return s; return fixup_tgetstr (s);}int SLtt_tgetnum (char *s){ if (Termcap_Initalized == 0) return -1;#ifdef USE_TERMCAP return tgetnum (s);#else return _SLtt_tigetnum (Terminfo, s);#endif}int SLtt_tgetflag (char *s){ if (Termcap_Initalized == 0) return -1;#ifdef USE_TERMCAP return tgetflag (s);#else return _SLtt_tigetflag (Terminfo, s);#endif}static int Vt100_Like = 0;void SLtt_get_terminfo (void){ char *term; int status; term = getenv ("TERM"); if (term == NULL) SLang_exit_error("TERM environment variable needs set."); if (0 == (status = SLtt_initialize (term))) return; if (status == -1) { SLang_exit_error ("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); } if (status == -2) { SLang_exit_error ("\Your terminal lacks the ability to clear the screen or position the cursor.\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -