sldisply.c

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 2,241 行 · 第 1/4 页

C
2,241
字号
#define TGETNUM tgetnum
#define TGETFLAG tgetflag
#endif

static char *my_tgetstr(char *what, char **p)
{
   register char *w, *w1;
   char *wsave;
   what = tgetstr(what, p);
   if (what != 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 *s)
{
#ifdef USE_TERMCAP
   static
#endif
     char *p = Tstr_Buf;
   return my_tgetstr (s, &p);
}

int SLtt_tgetnum (char *s)
{
   return TGETNUM (s);
}
int SLtt_tgetflag (char *s)
{
   return TGETFLAG (s);
}


static int Vt100_Like = 0;

void SLtt_get_terminfo (void)
{
   char *term, *t, ch;
   int is_xterm;
   int almost_vtxxx;

   get_color_info ();

   if (NULL == (term = (char *) getenv("TERM")))
     {
	SLang_exit_error("TERM environment variable needs set.");
     }

   Linux_Console = (!strncmp (term, "linux", 5)
#ifdef linux
		    || !strncmp(term, "con", 3)
#endif
		    );

   t = term;

   if (strcmp(t, "vt52") && (*t++ == 'v') && (*t++ == 't')
       && (ch = *t, (ch >= '1') && (ch <= '9'))) Vt100_Like = 1;

   is_xterm = !strncmp (term, "xterm", 5);
   almost_vtxxx = (Vt100_Like
		   || Linux_Console
		   || is_xterm
		   || !strcmp (term, "screen"));

#ifndef USE_TERMCAP
   if (NULL == (Tbuf = tgetent (term)))
     {
	char err_buf[512];
	if (almost_vtxxx) /* Special cases. */
	  {
	     int vt102 = 1;
	     if (!strcmp (term, "vt100")) vt102 = 0;
   	     SLtt_set_term_vtxxx (&vt102);
	     return;
	  }
	sprintf (err_buf, "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);
	SLang_exit_error(err_buf);
     }
   Tstr_Buf = Tbuf;
#else				       /* USE_TERMCAP */
   if (1 != tgetent(Tbuf, term)) SLang_exit_error("Unknown terminal.");
#endif				       /* NOT USE_TERMCAP */

   if ((NULL == (Cls_Str = SLtt_tgetstr("cl")))
       || (NULL == (Curs_Pos_Str = SLtt_tgetstr("cm"))))
     {
	SLang_exit_error("Terminal not powerful enough for SLang.");
     }

   if ((NULL == (Ins_Mode_Str = SLtt_tgetstr("im")))
       || ( NULL == (Eins_Mode_Str = SLtt_tgetstr("ei")))
       || ( NULL == (Del_Char_Str = SLtt_tgetstr("dc"))))
     SLtt_Term_Cannot_Insert = 1;

   Visible_Bell_Str = SLtt_tgetstr ("vb");
   Curs_Up_Str = SLtt_tgetstr ("up");
   Rev_Scroll_Str = SLtt_tgetstr("sr");
   Del_N_Lines_Str = SLtt_tgetstr("DL");
   Add_N_Lines_Str = SLtt_tgetstr("AL");

   /* Actually these are used to initialize terminals that use cursor
    * addressing.  Hard to believe.
    */
   Term_Init_Str = SLtt_tgetstr ("ti");
   Term_Reset_Str = SLtt_tgetstr ("te");

   /* If I do this for vtxxx terminals, arrow keys start sending ESC O A,
    * which I do not want.  This is mainly for HP terminals.
    */
   if ((almost_vtxxx == 0) || SLtt_Force_Keypad_Init)
     {
	Keypad_Init_Str = SLtt_tgetstr ("ks");
	Keypad_Reset_Str = SLtt_tgetstr ("ke");
     }

   /* Make up for defective termcap/terminfo databases */
   if ((Vt100_Like && (term[2] != '1'))
       || Linux_Console
       || is_xterm
       )
     {
	if (Del_N_Lines_Str == NULL) Del_N_Lines_Str = "\033[%dM";
	if (Add_N_Lines_Str == NULL) Add_N_Lines_Str = "\033[%dL";
     }

   Scroll_R_Str = SLtt_tgetstr("cs");

   SLtt_get_screen_size ();

   if ((Scroll_R_Str == NULL)
       || (((NULL == Del_N_Lines_Str) || (NULL == Add_N_Lines_Str))
	   && (NULL == Rev_Scroll_Str)))
     {
	if (is_xterm
	    || Linux_Console
	    )
	  {
	     /* Defective termcap mode!!!! */
	     SLtt_set_term_vtxxx (NULL);
	  }
	else SLtt_Term_Cannot_Scroll = 1;
     }

   Del_Eol_Str = SLtt_tgetstr("ce");

   Rev_Vid_Str = SLtt_tgetstr("mr");
   if (Rev_Vid_Str == NULL) Rev_Vid_Str = SLtt_tgetstr("so");

   Bold_Vid_Str = SLtt_tgetstr("md");

   /* Although xterm cannot blink, it does display the blinking characters
    * as bold ones.  Some Rxvt will display the background as high intensity.
    */
   if ((NULL == (Blink_Vid_Str = SLtt_tgetstr("mb")))
       && is_xterm)
     Blink_Vid_Str = "\033[5m";

   UnderLine_Vid_Str = SLtt_tgetstr("us");

   Start_Alt_Chars_Str = SLtt_tgetstr ("as");   /* smacs */
   End_Alt_Chars_Str = SLtt_tgetstr ("ae");   /* rmacs */
   Enable_Alt_Char_Set = SLtt_tgetstr ("eA");   /* enacs */
   SLtt_Graphics_Char_Pairs = SLtt_tgetstr ("ac");

#ifndef NCURSES_BRAIN_DAMAGE_CONTROL
# define NCURSES_BRAIN_DAMAGE_CONTROL 0
#endif

#if NCURSES_BRAIN_DAMAGE_CONTROL
   if (Linux_Console)
     {
# if 0
	char *lgcp = "l\332m\300k\277j\331u\264t\303v\301w\302q\304x\263n\053o\176s\137`\004a\260f\370g\361~\011,\020+\021.\031-\030h\261i\0250\333";

	SLtt_Graphics_Char_Pairs = lgcp;
	Start_Alt_Chars_Str = "\033(B\033)U\016";
	End_Alt_Chars_Str = "\033(B\033)0\017";
	Enable_Alt_Char_Set = NULL;
# else
	char *lgcp = "`\004a\261f\370g\361h\260j\331k\277l\332m\300n\305o\302q\304r\362s_t\303u\264v\301w\302x\263y\371z\372{\373|\374}\375~";

	SLtt_Graphics_Char_Pairs = lgcp;
	Start_Alt_Chars_Str = "\033[11m";
	End_Alt_Chars_Str = "\033[10m";
	Enable_Alt_Char_Set = NULL;
# endif
     }
#endif

   if (NULL == SLtt_Graphics_Char_Pairs)
     {
	/* make up for defective termcap/terminfo */
	if (Vt100_Like)
	  {
	     Start_Alt_Chars_Str = "\016";
	     End_Alt_Chars_Str = "\017";
	     Enable_Alt_Char_Set = "\033)0";
	  }
     }

    /* aixterm added by willi */
   if (is_xterm || !strncmp (term, "aixterm", 7))
     {
	Start_Alt_Chars_Str = "\016";
	End_Alt_Chars_Str = "\017";
	Enable_Alt_Char_Set = "\033(B\033)0";
     }

   if ((SLtt_Graphics_Char_Pairs == NULL) &&
       ((Start_Alt_Chars_Str == NULL) || (End_Alt_Chars_Str == NULL)))
     {
	SLtt_Has_Alt_Charset = 0;
	Enable_Alt_Char_Set = NULL;
     }
   else SLtt_Has_Alt_Charset = 1;


   /* status line capabilities */
   if ((SLtt_Has_Status_Line == -1)
       && (0 != (SLtt_Has_Status_Line = TGETFLAG ("hs"))))
     {
	Disable_Status_line_Str = SLtt_tgetstr ("ds");
	Return_From_Status_Line_Str = SLtt_tgetstr ("fs");
	Goto_Status_Line_Str = SLtt_tgetstr ("ts");
	Status_Line_Esc_Ok = TGETFLAG("es");
	Num_Status_Line_Columns = TGETNUM("ws");
	if (Num_Status_Line_Columns < 0) Num_Status_Line_Columns = 0;
     }

   if (NULL == (Norm_Vid_Str = SLtt_tgetstr("me")))
     {
	Norm_Vid_Str = SLtt_tgetstr("se");
     }

   Cursor_Invisible_Str = SLtt_tgetstr("vi");
   Cursor_Visible_Str = SLtt_tgetstr("ve");

   Curs_F_Str = SLtt_tgetstr("RI");

#if 0
   if (NULL != Curs_F_Str)
     {
	 Len_Curs_F_Str = strlen(Curs_F_Str);
     }
   else Len_Curs_F_Str = strlen(Curs_Pos_Str);
#endif

   Automatic_Margins = TGETFLAG ("am");
   /* No_Move_In_Standout = !TGETFLAG ("ms"); */
#ifdef HP_GLITCH_CODE
   Has_HP_Glitch = TGETFLAG ("xs");
#else
   Worthless_Highlight = TGETFLAG ("xs");
#endif

   if (Worthless_Highlight == 0)
     {				       /* Magic cookie glitch */
	Worthless_Highlight = (TGETNUM ("sg") > 0);
     }

   if (Worthless_Highlight)
     SLtt_Has_Alt_Charset = 0;

   /* Check for color information in the termcap.  A program should not
    * rely on this information being accurate.
    */
   if (SLtt_Use_Ansi_Colors == 0)
     {
	Reset_Color_String = SLtt_tgetstr ("op");

	SLtt_Use_Ansi_Colors = ((NULL != Reset_Color_String)
				|| (NULL != SLtt_tgetstr ("Sf"))
				|| (NULL != SLtt_tgetstr ("Sb"))
				|| (NULL != SLtt_tgetstr ("AF"))
				|| (NULL != SLtt_tgetstr ("AB"))
				|| (-1 != SLtt_tgetnum ("Co"))
				|| (-1 != SLtt_tgetnum ("pa")));

     }

#if defined(__QNX__) && defined(QNX_QANSI_SLANG_COMPAT_ACS)
   /*
    * Override the alt-char-set handling string in case of a
    * QNX/qansi terminal: use the "old style" strings in order
    * to be compatible with S-Lang without the SLTT_TRANSP_ACS_PATCH
    * code...
    */
   if (SLtt_Has_Alt_Charset &&
	    strncmp(term, "qansi", 5) == 0 &&
	    Start_Alt_Chars_Str[0] != '\016')
     {
        Start_Alt_Chars_Str = "\016"; /* smacs/as (^N) */
        End_Alt_Chars_Str = "\017";   /* rmacs/ae (^O) */
        SLtt_Graphics_Char_Pairs =    /* acsc/ac */
	    "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~O\141";

	/*
	 * it would be required to modify the sgr/sa entry also, if it
	 * would be used (->embedded as/ae sequences)...
	 */
     }
#endif /* __QNX__ && QNX_QANSI_SLANG_COMPAT_ACS */

}

#endif
/* Unix */

/* specific to vtxxx only */
void SLtt_enable_cursor_keys (void)
{
#ifdef __unix__
   if (Vt100_Like)
#endif
   SLtt_write_string("\033=\033[?1l");
}

#ifdef VMS
void SLtt_get_terminfo ()
{
   int zero = 0;

   get_color_info ();

   SLtt_set_term_vtxxx(&zero);
   Start_Alt_Chars_Str = "\016";
   End_Alt_Chars_Str = "\017";
   SLtt_Has_Alt_Charset = 1;
   SLtt_Graphics_Char_Pairs = "aaffgghhjjkkllmmnnooqqssttuuvvwwxx";
   Enable_Alt_Char_Set = "\033(B\033)0";
   SLtt_get_screen_size ();
}
#endif

/* This sets term for vt102 terminals it parameter vt100 is 0.  If vt100
 * is non-zero, set terminal appropriate for a only vt100
 * (no add line capability). */

void SLtt_set_term_vtxxx(int *vt100)
{
   Norm_Vid_Str = "\033[m";

   Scroll_R_Str = "\033[%i%d;%dr";
   Cls_Str = "\033[2J\033[H";
   Rev_Vid_Str = "\033[7m";
   Bold_Vid_Str = "\033[1m";
   Blink_Vid_Str = "\033[5m";
   UnderLine_Vid_Str = "\033[4m";
   Del_Eol_Str = "\033[K";
   Rev_Scroll_Str = "\033M";
   Curs_F_Str = "\033[%dC";
   /* Len_Curs_F_Str = 5; */
   Curs_Pos_Str = "\033[%i%d;%dH";
   if ((vt100 == NULL) || (*vt100 == 0))
     {
	Ins_Mode_Str = "\033[4h";
	Eins_Mode_Str = "\033[4l";
	Del_Char_Str =  "\033[P";
	Del_N_Lines_Str = "\033[%dM";
	Add_N_Lines_Str = "\033[%dL";
	SLtt_Term_Cannot_Insert = 0;
     }
   else
     {
	Del_N_Lines_Str = NULL;
	Add_N_Lines_Str = NULL;
	SLtt_Term_Cannot_Insert = 1;
     }
   SLtt_Term_Cannot_Scroll = 0;
   /* No_Move_In_Standout = 0; */
}

void SLtt_init_video (void)
{
   /*   send_string_to_term("\033[?6h"); */
   /* relative origin mode */
   SLtt_write_string (Term_Init_Str);
   SLtt_write_string (Keypad_Init_Str);
   SLtt_reset_scroll_region();
   SLtt_end_insert();
   SLtt_write_string (Enable_Alt_Char_Set);
   Video_Initialized = 1;
}


void SLtt_reset_video (void)
{
   SLtt_goto_rc (SLtt_Screen_Rows - 1, 0);
   Cursor_Set = 0;
   SLtt_normal_video ();	       /* MSKermit requires this  */
   SLtt_write_string(Norm_Vid_Str);

   Current_Fgbg = 0xFFFFFFFFU;
   SLtt_set_alt_char_set (0);
   if (SLtt_Use_Ansi_Colors)
     {
	if (Reset_Color_String == NULL)
	  {
	     SLtt_Char_Type attr;
	     if (-1 != make_color_fgbg (NULL, NULL, &attr))
	       write_attributes (attr);
	     else SLtt_write_string ("\033[0m\033[m");
	  }
	else SLtt_write_string (Reset_Color_String);
	Current_Fgbg = 0xFFFFFFFFU;
     }
   SLtt_erase_line ();
   SLtt_write_string (Keypad_Reset_Str);
   SLtt_write_string (Term_Reset_Str);
   SLtt_flush_output ();
   Video_Initialized = 0;
}

void SLtt_bold_video (void)
{
   SLtt_write_string (Bold_Vid_Str);
}

int SLtt_set_mouse_mode (int mode, int force)
{
   char *term;

   if (force == 0)
     {
	if (NULL == (term = (char *) getenv("TERM"))) return -1;
	if (strncmp ("xterm", term, 5))
	  return -1;
     }

   if (mode)
     SLtt_write_string ("\033[?9h");
   else
     SLtt_write_string ("\033[?9l");

   return 0;
}


void SLtt_disable_status_line (void)
{
   if (SLtt_Has_Status_Line > 0)
     SLtt_write_string (Disable_Status_line_Str);
}

int SLtt_write_to_status_line (char *s, int col)
{
   if ((SLtt_Has_Status_Line <= 0)
       || (Goto_Status_Line_Str == NULL)
       || (Return_From_Status_Line_Str == NULL))
     return -1;

   tt_printf (Goto_Status_Line_Str, col, 0);
   SLtt_write_string (s);
   SLtt_write_string (Return_From_Status_Line_Str);
   return 0;
}


void SLtt_get_screen_size (void)
{
#ifdef VMS
   int status, code;
   unsigned short chan;
   $DESCRIPTOR(dev_dsc, "SYS$INPUT:");
#endif
#ifdef __os2__
   VIOMODEINFO vioModeInfo;
#endif
   int r = 0, c = 0;

#if defined(TIOCGWINSZ) && !defined(SCO_FLAVOR)
   struct winsize wind_struct;

   do
     {
	if ((ioctl(1,TIOCGWINSZ,&wind_struct) == 0)
	    || (ioctl(0, TIOCGWINSZ, &wind_struct) == 0)
	    || (ioctl(2, TIOCGWINSZ, &wind_struct) == 0))
	  {
	     c = (int) wind_struct.ws_col;
	     r = (int) wind_struct.ws_row;
	     break;
	  }
     }
   while (errno == EINTR);

#endif

#ifdef VMS
   status = sys$assign(&dev_dsc,&chan,0,0,0);
   if (status & 1)
     {
	code = DVI$_DEVBUFSIZ;
	status = lib$getdvi(&code, &chan,0, &c, 0,0);
	if (!(status & 1))
	  c = 80;
	code = DVI$_TT_PAGE;
	status = lib$getdvi(&code, &chan,0, &r, 0,0);
	if (!(status & 1))
	  r = 24;
	sys$dassgn(chan);
     }
#endif

#ifdef __os2__
   vioModeInfo.cb = sizeof(vioModeInfo);
   VioGetMode (&vioModeInfo, 0);
   c = vioModeInfo.col;
   r = vioModeInfo.row;
#endif

   if (r <= 0)
     {
	char *s = getenv ("LINES");
	if (s != NULL) r = atoi (s);
     }

   if (c <= 0)
     {
	char *s = getenv ("COLUMNS");
	if (s != NULL) c = atoi (s);
     }

   if ((r <= 0) || (r > 200)) r = 24;
   if ((c <= 0) || (c > 250)) c = 80;
   SLtt_Screen_Rows = r;
   SLtt_Screen_Cols = c;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?