📄 slsmg.c
字号:
/* SLang Screen management routines *//* Copyright (c) 1992, 1999, 2001, 2002, 2003 John E. Davis * This file is part of the S-Lang library. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */#include "slinclud.h"#include "slang.h"#include "_slang.h"typedef struct Screen_Type { int n; /* number of chars written last time */ int flags; /* line untouched, etc... */ SLsmg_Char_Type *old, *neew;#ifndef IBMPC_SYSTEM unsigned long old_hash, new_hash;#endif }Screen_Type;#define TOUCHED 0x1#define TRASHED 0x2static int Screen_Trashed;Screen_Type SL_Screen[SLTT_MAX_SCREEN_ROWS];static int Start_Col, Start_Row;static int Screen_Cols, Screen_Rows;static int This_Row, This_Col;static int This_Color; /* only the first 8 bits of this * are used. The highest bit is used * to indicate an alternate character * set. This leaves 127 userdefineable * color combination. */#ifndef IBMPC_SYSTEM#define ALT_CHAR_FLAG 0x80#else#define ALT_CHAR_FLAG 0x00#endif#if SLTT_HAS_NON_BCE_SUPPORT && !defined(IBMPC_SYSTEM)#define REQUIRES_NON_BCE_SUPPORT 1static int Bce_Color_Offset;#endifint SLsmg_Newline_Behavior = 0;int SLsmg_Backspace_Moves = 0;/* Backward compatibility. Not used. *//* int SLsmg_Newline_Moves; */static void (*tt_normal_video)(void) = SLtt_normal_video;static void (*tt_goto_rc)(int, int) = SLtt_goto_rc;static void (*tt_cls) (void) = SLtt_cls;static void (*tt_del_eol) (void) = SLtt_del_eol;static void (*tt_smart_puts) (SLsmg_Char_Type *, SLsmg_Char_Type *, int, int) = SLtt_smart_puts;static int (*tt_flush_output) (void) = SLtt_flush_output;static int (*tt_reset_video) (void) = SLtt_reset_video;static int (*tt_init_video) (void) = SLtt_init_video;static int *tt_Screen_Rows = &SLtt_Screen_Rows;static int *tt_Screen_Cols = &SLtt_Screen_Cols;#ifndef IBMPC_SYSTEMstatic void (*tt_set_scroll_region)(int, int) = SLtt_set_scroll_region;static void (*tt_reverse_index)(int) = SLtt_reverse_index;static void (*tt_reset_scroll_region)(void) = SLtt_reset_scroll_region;static void (*tt_delete_nlines)(int) = SLtt_delete_nlines;#endif#ifndef IBMPC_SYSTEMstatic int *tt_Term_Cannot_Scroll = &SLtt_Term_Cannot_Scroll;static int *tt_Has_Alt_Charset = &SLtt_Has_Alt_Charset;static char **tt_Graphics_Char_Pairs = &SLtt_Graphics_Char_Pairs;static int *tt_Use_Blink_For_ACS = &SLtt_Use_Blink_For_ACS;#endifstatic int Smg_Inited;static void blank_line (SLsmg_Char_Type *p, int n, unsigned char ch){ register SLsmg_Char_Type *pmax = p + n; register SLsmg_Char_Type color_ch; color_ch = SLSMG_BUILD_CHAR(ch,This_Color); while (p < pmax) { *p++ = color_ch; }}static void clear_region (int row, int n, unsigned char ch){ int i; int imax = row + n; if (imax > Screen_Rows) imax = Screen_Rows; for (i = row; i < imax; i++) { if (i >= 0) { blank_line (SL_Screen[i].neew, Screen_Cols, ch); SL_Screen[i].flags |= TOUCHED; } }}void SLsmg_erase_eol (void){ int r, c; if (Smg_Inited == 0) return; c = This_Col - Start_Col; r = This_Row - Start_Row; if ((r < 0) || (r >= Screen_Rows)) return; if (c < 0) c = 0; else if (c >= Screen_Cols) return; blank_line (SL_Screen[This_Row].neew + c , Screen_Cols - c, ' '); SL_Screen[This_Row].flags |= TOUCHED;}static void scroll_up (void){ unsigned int i, imax; SLsmg_Char_Type *neew; neew = SL_Screen[0].neew; imax = Screen_Rows - 1; for (i = 0; i < imax; i++) { SL_Screen[i].neew = SL_Screen[i + 1].neew; SL_Screen[i].flags |= TOUCHED; } SL_Screen[i].neew = neew; SL_Screen[i].flags |= TOUCHED; blank_line (neew, Screen_Cols, ' '); This_Row--;}void SLsmg_gotorc (int r, int c){ This_Row = r; This_Col = c;}int SLsmg_get_row (void){ return This_Row;}int SLsmg_get_column (void){ return This_Col;}void SLsmg_erase_eos (void){ if (Smg_Inited == 0) return; SLsmg_erase_eol (); clear_region (This_Row + 1, Screen_Rows, ' ');}static int This_Alt_Char;void SLsmg_set_char_set (int i){#ifdef IBMPC_SYSTEM (void) i;#else if ((tt_Use_Blink_For_ACS != NULL) && (*tt_Use_Blink_For_ACS != 0)) return;/* alt chars not used and the alt bit * is used to indicate a blink. */ if (i) This_Alt_Char = ALT_CHAR_FLAG; else This_Alt_Char = 0; This_Color &= 0x7F; This_Color |= This_Alt_Char;#endif}void SLsmg_set_color (int color){ if (color < 0) return;#ifdef REQUIRES_NON_BCE_SUPPORT color += Bce_Color_Offset;#endif This_Color = color | This_Alt_Char;}void SLsmg_reverse_video (void){ SLsmg_set_color (1);}void SLsmg_normal_video (void){ SLsmg_set_color (0);}static int point_visible (int col_too){ return ((This_Row >= Start_Row) && (This_Row < Start_Row + Screen_Rows) && ((col_too == 0) || ((This_Col >= Start_Col) && (This_Col < Start_Col + Screen_Cols))));}void SLsmg_write_string (char *str){ SLsmg_write_nchars (str, strlen (str));}void SLsmg_write_nstring (char *str, unsigned int n){ unsigned int width; char blank = ' '; /* Avoid a problem if a user accidently passes a negative value */ if ((int) n < 0) return; if (str == NULL) width = 0; else { width = strlen (str); if (width > n) width = n; SLsmg_write_nchars (str, width); } while (width++ < n) SLsmg_write_nchars (&blank, 1);}void SLsmg_write_wrapped_string (char *s, int r, int c, unsigned int dr, unsigned int dc, int fill){ register char ch, *p; int maxc = (int) dc; if ((dr == 0) || (dc == 0)) return; p = s; dc = 0; while (1) { ch = *p++; if ((ch == 0) || (ch == '\n')) { int diff; diff = maxc - (int) dc; SLsmg_gotorc (r, c); SLsmg_write_nchars (s, dc); if (fill && (diff > 0)) { while (diff--) SLsmg_write_char (' '); } if ((ch == 0) || (dr == 1)) break; r++; dc = 0; dr--; s = p; } else if ((int) dc == maxc) { SLsmg_gotorc (r, c); SLsmg_write_nchars (s, dc + 1); if (dr == 1) break; r++; dc = 0; dr--; s = p; } else dc++; }}int SLsmg_Tab_Width = 8;/* Minimum value for which eight bit char is displayed as is. */#ifndef IBMPC_SYSTEMint SLsmg_Display_Eight_Bit = 160;static unsigned char Alt_Char_Set[129];/* 129th is used as a flag */#elseint SLsmg_Display_Eight_Bit = 128;#endifvoid SLsmg_write_nchars (char *str, unsigned int n){ register SLsmg_Char_Type *p, old, neew, color; unsigned char ch; unsigned int flags; int len, start_len, max_len; char *str_max; int newline_flag;#ifndef IBMPC_SYSTEM int alt_char_set_flag; alt_char_set_flag = ((This_Color & ALT_CHAR_FLAG) && ((tt_Use_Blink_For_ACS == NULL) || (*tt_Use_Blink_For_ACS == 0)));#endif if (Smg_Inited == 0) return; str_max = str + n; color = This_Color; top: /* get here only on newline */ newline_flag = 0; start_len = Start_Col; if (point_visible (0) == 0) return; len = This_Col; max_len = start_len + Screen_Cols; p = SL_Screen[This_Row - Start_Row].neew; if (len > start_len) p += (len - start_len); flags = SL_Screen[This_Row - Start_Row].flags; while ((len < max_len) && (str < str_max)) { ch = (unsigned char) *str++;#ifndef IBMPC_SYSTEM if (alt_char_set_flag) ch = Alt_Char_Set [ch & 0x7F];#endif if (((ch >= ' ') && (ch < 127)) || (ch >= (unsigned char) SLsmg_Display_Eight_Bit)#ifndef IBMPC_SYSTEM || alt_char_set_flag#endif ) { len += 1; if (len > start_len) { old = *p; neew = SLSMG_BUILD_CHAR(ch,color); if (old != neew) { flags |= TOUCHED; *p = neew; } p++; } } else if ((ch == '\t') && (SLsmg_Tab_Width > 0)) { n = len; n += SLsmg_Tab_Width; n = SLsmg_Tab_Width - (n % SLsmg_Tab_Width); if ((unsigned int) len + n > (unsigned int) max_len) n = (unsigned int) (max_len - len); neew = SLSMG_BUILD_CHAR(' ',color); while (n--) { len += 1; if (len > start_len) { if (*p != neew) { flags |= TOUCHED; *p = neew; } p++; } } } else if ((ch == '\n') && (SLsmg_Newline_Behavior != SLSMG_NEWLINE_PRINTABLE)) { newline_flag = 1; break; } else if ((ch == 0x8) && SLsmg_Backspace_Moves) { if (len != 0) len--; } else { if (ch & 0x80) { neew = SLSMG_BUILD_CHAR('~',color); len += 1; if (len > start_len) { if (*p != neew) { *p = neew; flags |= TOUCHED; } p++; if (len == max_len) break; ch &= 0x7F; } } len += 1; if (len > start_len) { neew = SLSMG_BUILD_CHAR('^',color); if (*p != neew) { *p = neew; flags |= TOUCHED; } p++; if (len == max_len) break; } if (ch == 127) ch = '?'; else ch = ch + '@'; len++; if (len > start_len) { neew = SLSMG_BUILD_CHAR(ch,color); if (*p != neew) { *p = neew; flags |= TOUCHED; } p++; } } } SL_Screen[This_Row - Start_Row].flags = flags; This_Col = len; if (SLsmg_Newline_Behavior == 0) return; if (newline_flag == 0) { while (str < str_max) { if (*str == '\n') break; str++; } if (str == str_max) return; str++; } This_Row++; This_Col = 0; if (This_Row == Start_Row + Screen_Rows) { if (SLsmg_Newline_Behavior == SLSMG_NEWLINE_SCROLLS) scroll_up (); } goto top;}void SLsmg_write_char (char ch){ SLsmg_write_nchars (&ch, 1);}static int Cls_Flag;void SLsmg_cls (void){ int tac; if (Smg_Inited == 0) return; tac = This_Alt_Char; This_Alt_Char = 0; SLsmg_set_color (0); clear_region (0, Screen_Rows, ' '); This_Alt_Char = tac; SLsmg_set_color (0); Cls_Flag = 1;}#if 0static void do_copy (SLsmg_Char_Type *a, SLsmg_Char_Type *b){ SLsmg_Char_Type *amax = a + Screen_Cols; while (a < amax) *a++ = *b++;}#endif#ifndef IBMPC_SYSTEMint SLsmg_Scroll_Hash_Border = 0;static unsigned long compute_hash (SLsmg_Char_Type *s, int n){ register unsigned long h = 0, g; register unsigned long sum = 0; register SLsmg_Char_Type *smax, ch; int is_blank = 2; s += SLsmg_Scroll_Hash_Border; smax = s + (n - SLsmg_Scroll_Hash_Border); while (s < smax) { ch = *s++; if (is_blank && (SLSMG_EXTRACT_CHAR(ch) != 32)) is_blank--; sum += ch; h = sum + (h << 3); if ((g = h & 0xE0000000UL) != 0) { h = h ^ (g >> 24); h = h ^ g; } } if (is_blank) return 0; return h;}static unsigned long Blank_Hash;static int try_scroll_down (int rmin, int rmax)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -