⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sltermin.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This file contains enough terminfo reading capabilities sufficient for
 * the slang SLtt interface.
 */

/* Copyright (c) 1992, 1995 John E. Davis
 * All rights reserved.
 *
 * You may distribute under the terms of either the GNU General Public
 * License or the Perl Artistic License.
 */

#include "config.h"

#include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif

#ifndef USE_SETUPTERM
#include "slang.h"
#include "_slang.h"

/*
 * The majority of the comments found in the file were taken from the
 * term(4) man page on an SGI.
 */

/* Short integers are stored in two 8-bit bytes.  The first byte contains
 * the least significant 8 bits of the value, and the second byte contains
 * the most significant 8 bits.  (Thus, the value represented is
 * 256*second+first.)  The value -1 is represented by 0377,0377, and the
 * value -2 is represented by 0376,0377; other negative values are illegal.
 * The -1 generally means that a capability is missing from this terminal.
 * The -2 means that the capability has been cancelled in the terminfo
 * source and also is to be considered missing.
 */

static int make_integer (unsigned char *buf)
{
   register int lo, hi;
   lo = (int) *buf++; hi = (int) *buf;
   if (hi == 0377)
     {
	if (lo == 0377) return -1;
	if (lo == 0376) return -2;
     }
   return lo + 256 * hi;
}

/*
 * The compiled file is created from the source file descriptions of the
 * terminals (see the -I option of infocmp) by using the terminfo compiler,
 * tic, and read by the routine setupterm [see curses(3X).]  The file is
 * divided into six parts in the following order:  the header, terminal
 * names, boolean flags, numbers, strings, and string table.
 *
 * The header section begins the file.  This section contains six short
 * integers in the format described below.  These integers are (1) the magic
 * number (octal 0432); (2) the size, in bytes, of the names section; (3)
 * the number of bytes in the boolean section; (4) the number of short
 * integers in the numbers section; (5) the number of offsets (short
 * integers) in the strings section; (6) the size, in bytes, of the string
 * table.
 */

#define MAGIC 0432

/* In this structure, all char * fields are malloced EXCEPT if the
 * structure is SLTERMCAP.  In that case, only terminal_names is malloced
 * and the other fields are pointers into it.
 */
typedef struct
{
#define SLTERMINFO 1
#define SLTERMCAP  2
   unsigned int flags;

   unsigned int name_section_size;
   char *terminal_names;

   unsigned int boolean_section_size;
   unsigned char *boolean_flags;

   unsigned int num_numbers;
   unsigned char *numbers;

   unsigned int num_string_offsets;
   unsigned char *string_offsets;

   unsigned int string_table_size;
   char *string_table;

} Terminfo_Type;

static char *tcap_getstr (char *, Terminfo_Type *);
static int tcap_getnum (char *, Terminfo_Type *);
static int tcap_getflag (char *, Terminfo_Type *);
static int tcap_getent (char *, Terminfo_Type *);

static FILE *open_terminfo (char *file, Terminfo_Type *h)
{
   FILE *fp;
   unsigned char buf[12];

   fp = fopen (file, "rb");
   if (fp == NULL) return NULL;

   if ((12 == fread ((char *) buf, 1, 12, fp) && (MAGIC == make_integer (buf))))
     {
	h->name_section_size = make_integer (buf + 2);
	h->boolean_section_size = make_integer (buf + 4);
	h->num_numbers = make_integer (buf + 6);
	h->num_string_offsets = make_integer (buf + 8);
	h->string_table_size = make_integer (buf + 10);
     }
   else
     {
	fclose (fp);
	fp = NULL;
     }
   return fp;
}

/*
 * The terminal names section comes next.  It contains the first line of the
 * terminfo description, listing the various names for the terminal,
 * separated by the bar ( | ) character (see term(5)).  The section is
 * terminated with an ASCII NUL character.
 */

/* returns pointer to malloced space */
static unsigned char *read_terminfo_section (FILE *fp, unsigned int size)
{
   char *s;

   if (NULL == (s = (char *) SLMALLOC (size))) return NULL;
   if (size != fread (s, 1, size, fp))
     {
	SLFREE (s);
	return NULL;
     }
   return (unsigned char *) s;
}

static char *read_terminal_names (FILE *fp, Terminfo_Type *t)
{
   return t->terminal_names = (char *) read_terminfo_section (fp, t->name_section_size);
}

/*
 * The boolean flags have one byte for each flag.  This byte is either 0 or
 * 1 as the flag is present or absent.  The value of 2 means that the flag
 * has been cancelled.  The capabilities are in the same order as the file
 * <term.h>.
 */

static unsigned char *read_boolean_flags (FILE *fp, Terminfo_Type *t)
{
   /* Between the boolean section and the number section, a null byte is
    * inserted, if necessary, to ensure that the number section begins on an
    * even byte offset. All short integers are aligned on a short word
    * boundary.
    */

   unsigned int size = (t->name_section_size + t->boolean_section_size) % 2;
   size += t->boolean_section_size;

   return t->boolean_flags = read_terminfo_section (fp, size);
}



/*
 * The numbers section is similar to the boolean flags section.  Each
 * capability takes up two bytes, and is stored as a short integer.  If the
 * value represented is -1 or -2, the capability is taken to be missing.
 */

static unsigned char *read_numbers (FILE *fp, Terminfo_Type *t)
{
   return t->numbers = read_terminfo_section (fp, 2 * t->num_numbers);
}


/* The strings section is also similar.  Each capability is stored as a
 * short integer, in the format above.  A value of -1 or -2 means the
 * capability is missing.  Otherwise, the value is taken as an offset from
 * the beginning of the string table.  Special characters in ^X or \c
 * notation are stored in their interpreted form, not the printing
 * representation.  Padding information ($<nn>) and parameter information
 * (%x) are stored intact in uninterpreted form.
 */

static unsigned char *read_string_offsets (FILE *fp, Terminfo_Type *t)
{
   return t->string_offsets = (unsigned char *) read_terminfo_section (fp, 2 * t->num_string_offsets);
}


/* The final section is the string table.  It contains all the values of
 * string capabilities referenced in the string section.  Each string is
 * null terminated.
 */

static char *read_string_table (FILE *fp, Terminfo_Type *t)
{
   return t->string_table = (char *) read_terminfo_section (fp, t->string_table_size);
}


/*
 * Compiled terminfo(4) descriptions are placed under the directory
 * /usr/share/lib/terminfo.  In order to avoid a linear search of a huge
 * UNIX system directory, a two-level scheme is used:
 * /usr/share/lib/terminfo/c/name where name is the name of the terminal,
 * and c is the first character of name.  Thus, att4425 can be found in the
 * file /usr/share/lib/terminfo/a/att4425.  Synonyms for the same terminal
 * are implemented by multiple links to the same compiled file.
 */

#define MAX_TI_DIRS 7
static char *Terminfo_Dirs [MAX_TI_DIRS] =
{
   NULL,
   "/usr/lib/terminfo",
   "/usr/share/lib/terminfo",
   "/usr/local/lib/terminfo",
   "/lib/terminfo",
   "/usr/local/share/terminfo",
   "/usr/share/terminfo"
};

char *SLtt_tigetent (char *term)
{
   char *tidir;
   int i;
   FILE *fp = NULL;
   char file[256];
   Terminfo_Type *ti;

   if (
       (term == NULL)
#ifdef SLANG_UNTIC
       && (SLang_Untic_Terminfo_File == NULL)
#endif
       )
     return NULL;

   if (NULL == (ti = (Terminfo_Type *) SLMALLOC (sizeof (Terminfo_Type))))
     {
	return NULL;
     }

#ifdef SLANG_UNTIC
   if (SLang_Untic_Terminfo_File != NULL)
     {
	fp = open_terminfo (SLang_Untic_Terminfo_File, ti);
	goto fp_open_label;
     }
   else
#endif
   /* If we are on a termcap based system, use termcap */
   if (0 == tcap_getent (term, ti)) return (char *) ti;

   Terminfo_Dirs[0] = getenv ("TERMINFO");
   i = 0;
   while (i < MAX_TI_DIRS)
     {
	tidir = Terminfo_Dirs[i];
	if (tidir != NULL)
	  {
	     sprintf (file, "%s/%c/%s", tidir, *term, term);
	     if (NULL != (fp = open_terminfo (file, ti))) break;
	  }
	i++;
     }
#ifdef SLANG_UNTIC
   fp_open_label:
#endif

   if (fp != NULL)
     {
	if (NULL != read_terminal_names (fp, ti))
	  {
	     if (NULL != read_boolean_flags (fp, ti))
	       {
		  if (NULL != read_numbers (fp, ti))
		    {
		       if (NULL != read_string_offsets (fp, ti))
			 {
			    if (NULL != read_string_table (fp, ti))
			      {
				 /* success */
				 fclose (fp);
				 ti->flags = SLTERMINFO;
				 return (char *) ti;
			      }
			    SLFREE (ti->string_offsets);
			 }
		       SLFREE (ti->numbers);
		    }
		  SLFREE (ti->boolean_flags);
	       }
	     SLFREE (ti->terminal_names);
	  }
	fclose (fp);
     }

   SLFREE (ti);
   return NULL;
}

#ifdef SLANG_UNTIC
# define UNTIC_COMMENT(x) ,x
#else
# define UNTIC_COMMENT(x)
#endif

typedef struct
{
   char name[3];
   int offset;
#ifdef SLANG_UNTIC
   char *comment;
#endif
}
Tgetstr_Map_Type;

/* I need to add: K1-5, %0-5(not important), @8, &8... */
static Tgetstr_Map_Type Tgetstr_Map [] =
{
   {"@7", 164 		UNTIC_COMMENT("KEY End")},
   {"AB", 360 		UNTIC_COMMENT("set a color background")},
   {"AF", 359 		UNTIC_COMMENT("set a color foreground")},
   {"AL", 110 		UNTIC_COMMENT("parm_insert_line")},
   {"DL", 106 		UNTIC_COMMENT("parm_delete_line")},
   {"RI", 112 		UNTIC_COMMENT("parm_right_cursor")},
   {"Sf", 302 		UNTIC_COMMENT("set foreground (color)")},
   {"Sb", 303 		UNTIC_COMMENT("set background (color)")},
   {"ac", 146 		UNTIC_COMMENT("acs_chars")},
   {"ae", 38 		UNTIC_COMMENT("exit_alt_charset_mode")},
   {"as", 25 		UNTIC_COMMENT("enter_alt_charset_mode")},
   {"ce", 6 		UNTIC_COMMENT("clr_eol")},
   {"cl", 5 		UNTIC_COMMENT("clear_screen")},
   {"cm", 10 		UNTIC_COMMENT("cursor_address")},
   {"cs", 3 		UNTIC_COMMENT("change_scroll_region")},
   {"dc", 21 		UNTIC_COMMENT("delete_character")},
   {"ds", 23 		UNTIC_COMMENT("disable status line")},
   {"eA", 155 		UNTIC_COMMENT("enable alt char set")},
   {"ei", 42 		UNTIC_COMMENT("exit_insert_mode")},
   {"fs", 47 		UNTIC_COMMENT("return from status line")},
   {"im", 31 		UNTIC_COMMENT("enter_insert_mode")},
   {"k0", 65 		UNTIC_COMMENT("key_f0")},
   {"k1", 66 		UNTIC_COMMENT("key_f1")},
   {"k2", 68 		UNTIC_COMMENT("key_f2")},
   {"k3", 69 		UNTIC_COMMENT("key_f3")},
   {"k4", 70 		UNTIC_COMMENT("key_f4")},
   {"k5", 71 		UNTIC_COMMENT("key_f5")},
   {"k6", 72 		UNTIC_COMMENT("key_f6")},
   {"k7", 73 		UNTIC_COMMENT("key_f7")},
   {"k8", 74 		UNTIC_COMMENT("key_f8")},
   {"k9", 75 		UNTIC_COMMENT("key_f9")},
   {"kA", 78 		UNTIC_COMMENT("key_il")},
   {"kC", 57 		UNTIC_COMMENT("key_clear")},
   {"kD", 59 		UNTIC_COMMENT("key_dc")},
   {"kE", 63 		UNTIC_COMMENT("key_eol,")},
   {"kF", 84 		UNTIC_COMMENT("key_sf")},
   {"kH", 80 		UNTIC_COMMENT("key_ll")},
   {"kI", 77 		UNTIC_COMMENT("key_ic")},
   {"kL", 60 		UNTIC_COMMENT("key_dl")},
   {"kM", 62 		UNTIC_COMMENT("key_eic,")},
   {"kN", 81 		UNTIC_COMMENT("key_npage")},
   {"kP", 82 		UNTIC_COMMENT("key_ppage")},
   {"kR", 85 		UNTIC_COMMENT("key_sr")},
   {"kS", 64 		UNTIC_COMMENT("key_eos,")},
   {"kT", 86 		UNTIC_COMMENT("key_stab")},
   {"ka", 56 		UNTIC_COMMENT("key_catab")},
   {"k;", 67 		UNTIC_COMMENT("key_f10")},
   {"kb", 55 		UNTIC_COMMENT("key_backspace")},
   {"kd", 61 		UNTIC_COMMENT("key_down")},
   {"ke", 88 		UNTIC_COMMENT("End keypad transmit mode")},
   {"kh", 76 		UNTIC_COMMENT("key_home")},
   {"kl", 79 		UNTIC_COMMENT("key_left")},
   {"kr", 83 		UNTIC_COMMENT("key_right")},
   {"ks", 89 		UNTIC_COMMENT("Start keypad transmit mode")},
   {"kt", 58 		UNTIC_COMMENT("key_ctab")},
   {"ku", 87 		UNTIC_COMMENT("key_up")},
   {"mb", 26 		UNTIC_COMMENT("enter_blink_mode")},
   {"md", 27 		UNTIC_COMMENT("enter_bold_mode")},
   {"me", 39 		UNTIC_COMMENT("exit_attribute_mode")},
   {"mr", 34 		UNTIC_COMMENT("enter_reverse_mode")},
   {"op", 297 		UNTIC_COMMENT("orig_pair (color)")},
   {"pf", 119 		UNTIC_COMMENT("turn OFF printer")},
   {"po", 120 		UNTIC_COMMENT("turn ON printer")},
   {"se", 43 		UNTIC_COMMENT("exit_standout_mode")},
   {"so", 35 		UNTIC_COMMENT("enter_standout_mode")},
   {"sr", 130 		UNTIC_COMMENT("scroll_reverse")},
   {"te", 40 		UNTIC_COMMENT("end cursor addressing")},
   {"ti", 28 		UNTIC_COMMENT("begin cursor addressing")},
   {"ts", 135 		UNTIC_COMMENT("goto to status line")},
   {"up", 19 		UNTIC_COMMENT("cursor_up")},
   {"us", 36 		UNTIC_COMMENT("enter_underline_mode")},
   {"vb", 45 		UNTIC_COMMENT("flash_screen")},
   {"ve", 16 		UNTIC_COMMENT("make cursor very visible")},
   {"vi", 13 		UNTIC_COMMENT("make cursor invisible")},
   {"vs", 20 		UNTIC_COMMENT("make cursor very visible")},
   {"", 0 		UNTIC_COMMENT(NULL)}
};

static int compute_cap_offset (char *cap, Terminfo_Type *t, Tgetstr_Map_Type *map, unsigned int max_ofs)
{
   char cha, chb;

   (void) t;
   cha = *cap++; chb = *cap;

   while (*map->name != 0)
     {
	if ((cha == *map->name) && (chb == *(map->name + 1)))
	  {
	     if (map->offset >= (int) max_ofs) return -1;
	     return map->offset;
	  }
	map++;
     }
   return -1;
}


char *SLtt_tigetstr (char *cap, char **pp)
{
   int offset;
   Terminfo_Type *t;

   if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return NULL;

   if (t->flags == SLTERMCAP) return tcap_getstr (cap, t);

   offset = compute_cap_offset (cap, t, Tgetstr_Map, t->num_string_offsets);
   if (offset < 0) return NULL;
   offset = make_integer (t->string_offsets + 2 * offset);
   if (offset < 0) return NULL;
   return t->string_table + offset;
}

static Tgetstr_Map_Type Tgetnum_Map[] =
{
   {"co", 0		UNTIC_COMMENT("columns")},
   {"li", 2		UNTIC_COMMENT("lines")},
   {"Co", 13		UNTIC_COMMENT("max colors")},
   {"pa", 14		UNTIC_COMMENT("max pairs")},
   {"sg", 4		UNTIC_COMMENT("magic cookie glitch")},
   {"ws", 7		UNTIC_COMMENT("num columns in status line")},
   {"", -1		UNTIC_COMMENT(NULL)}
};

int SLtt_tigetnum (char *cap, char **pp)

⌨️ 快捷键说明

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