sldisply.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,241 行 · 第 1/4 页
C
2,241 行
static void write_attributes (SLtt_Char_Type fgbg)
{
int bg0, fg0;
if (Worthless_Highlight) return;
if (fgbg == Current_Fgbg) return;
/* Before spitting out colors, fix attributes */
if ((fgbg & ATTR_MASK) != (Current_Fgbg & ATTR_MASK))
{
if (Current_Fgbg & ATTR_MASK)
{
SLtt_write_string(Norm_Vid_Str);
/* In case normal video turns off ALL attributes: */
if (fgbg & SLTT_ALTC_MASK)
Current_Fgbg &= ~SLTT_ALTC_MASK;
SLtt_set_alt_char_set (0);
}
if ((fgbg & SLTT_ALTC_MASK)
!= (Current_Fgbg & SLTT_ALTC_MASK))
{
SLtt_set_alt_char_set ((int) (fgbg & SLTT_ALTC_MASK));
}
if (fgbg & SLTT_ULINE_MASK) SLtt_write_string (UnderLine_Vid_Str);
if (fgbg & SLTT_BOLD_MASK) SLtt_bold_video ();
if (fgbg & SLTT_REV_MASK) SLtt_write_string (Rev_Vid_Str);
if (fgbg & SLTT_BLINK_MASK)
{
/* Someday Linux will have a blink mode that set high intensity
* background. Lets be prepared.
*/
if (SLtt_Blink_Mode) SLtt_write_string (Blink_Vid_Str);
}
}
if (SLtt_Use_Ansi_Colors)
{
fg0 = (int) GET_FG(fgbg);
bg0 = (int) GET_BG(fgbg);
tt_printf(Color_Escape_Sequence, fg0, bg0);
}
Current_Fgbg = fgbg;
}
static int Video_Initialized;
void SLtt_reverse_video (int color)
{
SLtt_Char_Type fgbg;
char *esc;
if (Worthless_Highlight) return;
if ((color < 0) || (color >= JMAX_COLORS)) return;
if (Video_Initialized == 0)
{
if (color == JNORMAL_COLOR)
{
SLtt_write_string (Norm_Vid_Str);
}
else SLtt_write_string (Rev_Vid_Str);
Current_Fgbg = 0xFFFFFFFFU;
return;
}
if (SLtt_Use_Ansi_Colors)
{
fgbg = Ansi_Color_Map[color].fgbg;
if ((esc = Ansi_Color_Map[color].custom_esc) != NULL)
{
if (fgbg != Current_Fgbg)
{
Current_Fgbg = fgbg;
SLtt_write_string (esc);
return;
}
}
}
else fgbg = Ansi_Color_Map[color].mono;
if (fgbg == Current_Fgbg) return;
write_attributes (fgbg);
}
void SLtt_normal_video (void)
{
SLtt_reverse_video(JNORMAL_COLOR);
}
void SLtt_narrow_width (void)
{
SLtt_write_string("\033[?3l");
}
void SLtt_wide_width (void)
{
SLtt_write_string("\033[?3h");
}
/* Highest bit represents the character set. */
#define COLOR_MASK 0x7F00
#define COLOR_OF(x) (((unsigned int)(x) & COLOR_MASK) >> 8)
/*
#define COLOR_EQS(a, b) \
(Ansi_Color_Map[COLOR_OF(a)].fgbg == Ansi_Color_Map[COLOR_OF(b)].fgbg)
*/
#define COLOR_EQS(a, b) \
(SLtt_Use_Ansi_Colors \
? (Ansi_Color_Map[COLOR_OF(a)].fgbg == Ansi_Color_Map[COLOR_OF(b)].fgbg)\
: (Ansi_Color_Map[COLOR_OF(a)].mono == Ansi_Color_Map[COLOR_OF(b)].mono))
#define CHAR_EQS(a, b) (((a) == (b))\
|| ((((a) & ~COLOR_MASK) == ((b) & ~COLOR_MASK))\
&& COLOR_EQS((a), (b))))
/* The whole point of this routine is to prevent writing to the last column
* and last row on terminals with automatic margins.
*/
static void write_string_with_care (char *str)
{
unsigned int len;
if (str == NULL) return;
len = strlen (str);
if (Automatic_Margins && (Cursor_r + 1 == SLtt_Screen_Rows))
{
if (len + (unsigned int) Cursor_c >= (unsigned int) SLtt_Screen_Cols)
{
/* For now, just do not write there. Later, something more
* sophisticated will be implemented.
*/
if (SLtt_Screen_Cols > Cursor_c)
len = SLtt_Screen_Cols - Cursor_c - 1;
else len = 0;
}
}
tt_write (str, len);
}
static void send_attr_str (unsigned short *s)
{
unsigned char out[256], ch, *p;
register SLtt_Char_Type attr;
register unsigned short sh;
int color, last_color = -1;
p = out;
while (0 != (sh = *s++))
{
ch = sh & 0xFF;
color = ((int) sh & 0xFF00) >> 8;
#ifdef SLTT_TRANSP_ACS_PATCH
if (ch <= ' ' && (color & 0x80)) color &= ~0x80;
#endif
if (color != last_color)
{
if (SLtt_Use_Ansi_Colors) attr = Ansi_Color_Map[color & 0x7F].fgbg;
else attr = Ansi_Color_Map[color & 0x7F].mono;
/* sh => color */
if (color & 0x80) /* alternate char set */
{
if (SLtt_Use_Blink_For_ACS)
{
if (SLtt_Blink_Mode) attr |= SLTT_BLINK_MASK;
}
else attr |= SLTT_ALTC_MASK;
}
if (attr != Current_Fgbg)
{
#ifndef SLTT_TRANSP_ACS_PATCH
if ((ch != ' ') ||
/* it is a space so only consider it different if it
* has different attributes.
*/
(attr & BGALL_MASK) != (Current_Fgbg & BGALL_MASK))
#endif
{
if (p != out)
{
*p = 0;
write_string_with_care ((char *) out);
Cursor_c += (int) (p - out);
p = out;
}
if (SLtt_Use_Ansi_Colors && (NULL != Ansi_Color_Map[color & 0x7F].custom_esc))
{
SLtt_write_string (Ansi_Color_Map[color & 0x7F].custom_esc);
/* Just in case the custom escape sequence screwed up
* the alt character set state...
*/
if ((attr & SLTT_ALTC_MASK) != (Current_Fgbg & SLTT_ALTC_MASK))
SLtt_set_alt_char_set ((int) (attr & SLTT_ALTC_MASK));
Current_Fgbg = attr;
}
else write_attributes (attr);
last_color = color;
}
}
}
*p++ = ch;
}
*p = 0;
if (p != out) write_string_with_care ((char *) out);
Cursor_c += (int) (p - out);
}
static void forward_cursor (unsigned int n, int row)
{
char buf[30];
if (n <= 4)
{
SLtt_normal_video ();
SLMEMSET (buf, ' ', n);
buf[n] = 0;
write_string_with_care (buf);
Cursor_c += n;
}
else if (Curs_F_Str != NULL)
{
Cursor_c += n;
n = tt_sprintf(buf, Curs_F_Str, (int) n, 0);
tt_write(buf, n);
}
else SLtt_goto_rc (row, (int) (Cursor_c + n));
}
#define SPACE_CHAR (0x20 | (JNORMAL_COLOR << 8))
void SLtt_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int row)
{
register unsigned short *p, *q, *qmax, *pmax, *buf;
unsigned short buffer[256];
unsigned int n_spaces;
unsigned short *space_match, *last_buffered_match;
#ifdef HP_GLITCH_CODE
int handle_hp_glitch = 0;
#endif
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++;
}
/*position the cursor */
SLtt_goto_rc (row, (int) (p - neww));
#ifdef HP_GLITCH_CODE
if (Has_HP_Glitch)
{
unsigned short *qq = q;
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 */
while (qmax > q)
{
qmax--;
if (!CHAR_EQS(*qmax, SPACE_CHAR))
{
qmax++;
break;
}
}
while (pmax > p)
{
pmax--;
if (!CHAR_EQS(*pmax, SPACE_CHAR))
{
pmax++;
break;
}
}
last_buffered_match = buf = buffer; /* buffer is empty */
#ifdef HP_GLITCH_CODE
if (handle_hp_glitch)
{
while (p < pmax)
{
*buf++ = *p++;
}
}
#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,SPACE_CHAR) && CHAR_EQS(*p, SPACE_CHAR))
{
/* 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,SPACE_CHAR)
&& CHAR_EQS(*p, SPACE_CHAR))
{
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++;
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;
if (buf != buffer) send_attr_str (buffer);
buf = buffer;
if (n_spaces && (p < pmax))
{
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.
*/
#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++ = SPACE_CHAR;
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;
}
}
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_del_eol ();
if (Automatic_Margins && (Cursor_c + 1 >= SLtt_Screen_Cols)) Cursor_Set = 0;
}
static void get_color_info (void)
{
char *fg, *bg;
SLtt_Use_Ansi_Colors = (NULL != getenv ("COLORTERM"));
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__
#ifndef USE_TERMCAP
static char *Tbuf;
static char *Tstr_Buf;
#define tgetstr SLtt_tigetstr
#define tgetent SLtt_tigetent
#define TGETNUM(x) SLtt_tigetnum((x), &Tbuf)
#define TGETFLAG(x) SLtt_tigetflag((x), &Tbuf)
#else
extern char *tgetstr(char *, char **);
extern int tgetent(char *, char *);
extern int tgetnum(char *);
extern int tgetflag(char *);
static char Tstr_Buf[1024];
static char Tbuf[4096];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?