📄 slsmg.c
字号:
{ int i, r1, r2, di, j; unsigned long hash; int did_scroll; int color; SLsmg_Char_Type *tmp; int ignore; did_scroll = 0; for (i = rmax; i > rmin; i--) { hash = SL_Screen[i].new_hash; if (hash == Blank_Hash) continue; if ((hash == SL_Screen[i].old_hash)#if 0 || ((i + 1 < Screen_Rows) && (hash == SL_Screen[i + 1].old_hash)) || ((i - 1 > rmin) && (SL_Screen[i].old_hash == SL_Screen[i - 1].new_hash))#endif ) continue; for (j = i - 1; j >= rmin; j--) { if (hash == SL_Screen[j].old_hash) break; } if (j < rmin) continue; r2 = i; /* end scroll region */ di = i - j; j--; ignore = 0; while ((j >= rmin) && (SL_Screen[j].old_hash == SL_Screen[j + di].new_hash)) { if (SL_Screen[j].old_hash == Blank_Hash) ignore++; j--; } r1 = j + 1; /* If this scroll only scrolls this line into place, don't do it. */ if ((di > 1) && (r1 + di + ignore == r2)) continue; /* If there is anything in the scrolling region that is ok, abort the * scroll. */ for (j = r1; j <= r2; j++) { if ((SL_Screen[j].old_hash != Blank_Hash) && (SL_Screen[j].old_hash == SL_Screen[j].new_hash)) { /* See if the scroll is happens to scroll this one into place. */ if ((j + di > r2) || (SL_Screen[j].old_hash != SL_Screen[j + di].new_hash)) break; } } if (j <= r2) continue; color = This_Color; This_Color = 0; did_scroll = 1; (*tt_normal_video) (); (*tt_set_scroll_region) (r1, r2); (*tt_goto_rc) (0, 0); (*tt_reverse_index) (di); (*tt_reset_scroll_region) (); /* Now we have a hole in the screen. * Make the virtual screen look like it. * * Note that if the terminal does not support BCE, then we have * no idea what color the hole is. So, for this case, we do not * want to add Bce_Color_Offset to This_Color since if Bce_Color_Offset * is non-zero, then This_Color = 0 does not match any valid color * obtained by adding Bce_Color_Offset. */ for (j = r1; j <= r2; j++) SL_Screen[j].flags = TOUCHED; while (di--) { tmp = SL_Screen[r2].old; for (j = r2; j > r1; j--) { SL_Screen[j].old = SL_Screen[j - 1].old; SL_Screen[j].old_hash = SL_Screen[j - 1].old_hash; } SL_Screen[r1].old = tmp; blank_line (SL_Screen[r1].old, Screen_Cols, ' '); SL_Screen[r1].old_hash = Blank_Hash; r1++; } This_Color = color; } return did_scroll;}static int try_scroll_up (int rmin, int rmax){ int i, r1, r2, di, j; unsigned long hash; int did_scroll; int color; SLsmg_Char_Type *tmp; int ignore; did_scroll = 0; for (i = rmin; i < rmax; i++) { hash = SL_Screen[i].new_hash; if (hash == Blank_Hash) continue; if (hash == SL_Screen[i].old_hash) continue; /* find a match further down screen */ for (j = i + 1; j <= rmax; j++) { if (hash == SL_Screen[j].old_hash) break; } if (j > rmax) continue; r1 = i; /* beg scroll region */ di = j - i; /* number of lines to scroll */ j++; /* since we know this is a match */ /* find end of scroll region */ ignore = 0; while ((j <= rmax) && (SL_Screen[j].old_hash == SL_Screen[j - di].new_hash)) { if (SL_Screen[j].old_hash == Blank_Hash) ignore++; j++; } r2 = j - 1; /* end of scroll region */ /* If this scroll only scrolls this line into place, don't do it. */ if ((di > 1) && (r1 + di + ignore == r2)) continue; /* If there is anything in the scrolling region that is ok, abort the * scroll. */ for (j = r1; j <= r2; j++) { if ((SL_Screen[j].old_hash != Blank_Hash) && (SL_Screen[j].old_hash == SL_Screen[j].new_hash)) { if ((j - di < r1) || (SL_Screen[j].old_hash != SL_Screen[j - di].new_hash)) break; } } if (j <= r2) continue; did_scroll = 1; /* See the above comments about BCE */ color = This_Color; This_Color = 0; (*tt_normal_video) (); (*tt_set_scroll_region) (r1, r2); (*tt_goto_rc) (0, 0); /* relative to scroll region */ (*tt_delete_nlines) (di); (*tt_reset_scroll_region) (); /* Now we have a hole in the screen. Make the virtual screen look * like it. */ for (j = r1; j <= r2; j++) SL_Screen[j].flags = TOUCHED; while (di--) { tmp = SL_Screen[r1].old; for (j = r1; j < r2; j++) { SL_Screen[j].old = SL_Screen[j + 1].old; SL_Screen[j].old_hash = SL_Screen[j + 1].old_hash; } SL_Screen[r2].old = tmp; blank_line (SL_Screen[r2].old, Screen_Cols, ' '); SL_Screen[r2].old_hash = Blank_Hash; r2--; } This_Color = color; } return did_scroll;}static void try_scroll (void){ int r1, rmin, rmax; int num_up, num_down; /* find region limits. */ for (rmax = Screen_Rows - 1; rmax > 0; rmax--) { if (SL_Screen[rmax].new_hash != SL_Screen[rmax].old_hash) { r1 = rmax - 1; if ((r1 == 0) || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash)) break; rmax = r1; } } for (rmin = 0; rmin < rmax; rmin++) { if (SL_Screen[rmin].new_hash != SL_Screen[rmin].old_hash) { r1 = rmin + 1; if ((r1 == rmax) || (SL_Screen[r1].new_hash != SL_Screen[r1].old_hash)) break; rmin = r1; } } /* Below, we have two scrolling algorithms. The first has the effect of * scrolling lines down. This is usually appropriate when one moves * up the display, e.g., with the UP arrow. The second algorithm is * appropriate for going the other way. It is important to choose the * correct one. */ num_up = 0; for (r1 = rmin; r1 < rmax; r1++) { if (SL_Screen[r1].new_hash == SL_Screen[r1 + 1].old_hash) num_up++; } num_down = 0; for (r1 = rmax; r1 > rmin; r1--) { if (SL_Screen[r1 - 1].old_hash == SL_Screen[r1].new_hash) num_down++; } if (num_up > num_down) { if (try_scroll_up (rmin, rmax)) return; (void) try_scroll_down (rmin, rmax); } else { if (try_scroll_down (rmin, rmax)) return; (void) try_scroll_up (rmin, rmax); }}#endif /* NOT IBMPC_SYSTEM */#ifdef REQUIRES_NON_BCE_SUPPORTstatic void adjust_colors (void){ int bce; int i; bce = Bce_Color_Offset; Bce_Color_Offset = _SLtt_get_bce_color_offset (); if (bce == Bce_Color_Offset) return; if ((tt_Use_Blink_For_ACS != NULL) && (*tt_Use_Blink_For_ACS != 0)) return; /* this mode does not support non-BCE * terminals. */ for (i = 0; i < Screen_Rows; i++) { SLsmg_Char_Type *s, *smax; SL_Screen[i].flags |= TRASHED; s = SL_Screen[i].neew; smax = s + Screen_Cols; while (s < smax) { int color = (int) SLSMG_EXTRACT_COLOR(*s); int acs; if (color < 0) { s++; continue; } acs = color & 0x80; color = (color & 0x7F) - bce; color += Bce_Color_Offset; if (color >= 0) { unsigned char ch = SLSMG_EXTRACT_CHAR(*s); *s = SLSMG_BUILD_CHAR(ch, ((color&0x7F)|acs)); } s++; } }}#endifvoid SLsmg_refresh (void){ int i;#ifndef IBMPC_SYSTEM int trashed = 0;#endif if (Smg_Inited == 0) return; if (Screen_Trashed) { Cls_Flag = 1; for (i = 0; i < Screen_Rows; i++) SL_Screen[i].flags |= TRASHED;#ifdef REQUIRES_NON_BCE_SUPPORT adjust_colors ();#endif }#ifndef IBMPC_SYSTEM for (i = 0; i < Screen_Rows; i++) { if (SL_Screen[i].flags == 0) continue; SL_Screen[i].new_hash = compute_hash (SL_Screen[i].neew, Screen_Cols); trashed = 1; }#endif if (Cls_Flag) { (*tt_normal_video) (); (*tt_cls) (); }#ifndef IBMPC_SYSTEM else if (trashed && (*tt_Term_Cannot_Scroll == 0)) try_scroll ();#endif for (i = 0; i < Screen_Rows; i++) { if (SL_Screen[i].flags == 0) continue; if (Cls_Flag || SL_Screen[i].flags & TRASHED) { int color = This_Color; if (Cls_Flag == 0) { (*tt_goto_rc) (i, 0); (*tt_del_eol) (); } This_Color = 0; blank_line (SL_Screen[i].old, Screen_Cols, ' '); This_Color = color; } SL_Screen[i].old[Screen_Cols] = 0; SL_Screen[i].neew[Screen_Cols] = 0; (*tt_smart_puts) (SL_Screen[i].neew, SL_Screen[i].old, Screen_Cols, i); SLMEMCPY ((char *) SL_Screen[i].old, (char *) SL_Screen[i].neew, Screen_Cols * sizeof (SLsmg_Char_Type)); SL_Screen[i].flags = 0;#ifndef IBMPC_SYSTEM SL_Screen[i].old_hash = SL_Screen[i].new_hash;#endif } if (point_visible (1)) (*tt_goto_rc) (This_Row - Start_Row, This_Col - Start_Col); (*tt_flush_output) (); Cls_Flag = 0; Screen_Trashed = 0;}static int compute_clip (int row, int n, int box_start, int box_end, int *rmin, int *rmax){ int row_max; if (n < 0) return 0; if (row >= box_end) return 0; row_max = row + n; if (row_max <= box_start) return 0; if (row < box_start) row = box_start; if (row_max >= box_end) row_max = box_end; *rmin = row; *rmax = row_max; return 1;}void SLsmg_touch_lines (int row, unsigned int n){ int i; int r1, r2; /* Allow this function to be called even when we are not initialied. * Calling this function is useful after calling SLtt_set_color * to force the display to be redrawn */ if (Smg_Inited == 0) return; if (0 == compute_clip (row, (int) n, Start_Row, Start_Row + Screen_Rows, &r1, &r2)) return; r1 -= Start_Row; r2 -= Start_Row; for (i = r1; i < r2; i++) { SL_Screen[i].flags |= TRASHED; }}void SLsmg_touch_screen (void){ Screen_Trashed = 1;} #ifndef IBMPC_SYSTEMstatic SLCONST char Fake_Alt_Char_Pairs [] = "a:j+k+l+m+q-t+u+v+w+x|n+`+f\\g#~o,<+>.v-^h#0#";static void init_alt_char_set (void){ int i; unsigned SLCONST char *p, *pmax; unsigned char ch; if (Alt_Char_Set[128] == 128) return; i = 32; memset ((char *)Alt_Char_Set, ' ', i); while (i <= 128) { Alt_Char_Set [i] = i; i++; } /* Map to VT100 */ if (*tt_Has_Alt_Charset) { if (tt_Graphics_Char_Pairs == NULL) p = NULL; else p = (unsigned char *) *tt_Graphics_Char_Pairs; if (p == NULL) return; } else p = (unsigned SLCONST char *) Fake_Alt_Char_Pairs; pmax = p + strlen ((SLCONST char *) p); /* Some systems have messed up entries for this */ while (p < pmax) { ch = *p++; ch &= 0x7F; /* should be unnecessary */ Alt_Char_Set [ch] = *p; p++; }}#endif#ifndef IBMPC_SYSTEM# define BLOCK_SIGNALS SLsig_block_signals ()# define UNBLOCK_SIGNALS SLsig_unblock_signals ()#else# define BLOCK_SIGNALS (void)0# define UNBLOCK_SIGNALS (void)0#endifstatic int Smg_Suspended;int SLsmg_suspend_smg (void){ BLOCK_SIGNALS; if (Smg_Suspended == 0) { (*tt_reset_video) (); Smg_Suspended = 1; } UNBLOCK_SIGNALS; return 0;}int SLsmg_resume_smg (void){ BLOCK_SIGNALS; if (Smg_Suspended == 0) { UNBLOCK_SIGNALS; return 0; } Smg_Suspended = 0; if (-1 == (*tt_init_video) ()) { UNBLOCK_SIGNALS; return -1; } Cls_Flag = 1; SLsmg_touch_screen (); SLsmg_refresh (); UNBLOCK_SIGNALS; return 0;} static void reset_smg (void){ int i; if (Smg_Inited == 0) return; for (i = 0; i < Screen_Rows; i++) { SLfree ((char *)SL_Screen[i].old); SLfree ((char *)SL_Screen[i].neew);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -