term.c
上传用户:gddssl
上传日期:2007-01-06
资源大小:1003k
文件大小:95k
源码类别:

编辑器/阅读器

开发平台:

DOS

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8. /*
  9.  *
  10.  * term.c: functions for controlling the terminal
  11.  *
  12.  * primitive termcap support for Amiga, MSDOS, and Win32 included
  13.  *
  14.  * NOTE: padding and variable substitution is not performed,
  15.  * when compiling without HAVE_TGETENT, we use tputs() and tgoto() dummies.
  16.  */
  17. /*
  18.  * Some systems have a prototype for tgetstr() with (char *) instead of
  19.  * (char **). This define removes that prototype. We include our own prototype
  20.  * below.
  21.  */
  22. #define tgetstr tgetstr_defined_wrong
  23. #include "vim.h"
  24. #ifdef HAVE_TGETENT
  25. # ifdef HAVE_TERMIOS_H
  26. #  include <termios.h>     /* seems to be required for some Linux */
  27. # endif
  28. # ifdef HAVE_TERMCAP_H
  29. #  include <termcap.h>
  30. # endif
  31. /*
  32.  * A few linux systems define outfuntype in termcap.h to be used as the third
  33.  * argument for tputs().
  34.  */
  35. # ifdef VMS
  36. #  define TPUTSFUNCAST
  37. # else
  38. #  ifdef HAVE_OUTFUNTYPE
  39. #   define TPUTSFUNCAST (outfuntype)
  40. #  else
  41. #   define TPUTSFUNCAST (int (*)())
  42. #  endif
  43. # endif
  44. #endif
  45. #undef tgetstr
  46. /*
  47.  * Here are the builtin termcap entries.  They are not stored as complete
  48.  * Tcarr structures, as such a structure is too big.
  49.  *
  50.  * The entries are compact, therefore they normally are included even when
  51.  * HAVE_TGETENT is defined. When HAVE_TGETENT is defined, the builtin entries
  52.  * can be accessed with "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
  53.  *
  54.  * Each termcap is a list of builtin_term structures. It always starts with
  55.  * KS_NAME, which separates the entries.  See parse_builtin_tcap() for all
  56.  * details.
  57.  * bt_entry is either a KS_xxx code (< 0x100), or a K_xxx code.
  58.  */
  59. struct builtin_term
  60. {
  61.     int bt_entry;
  62.     char *bt_string;
  63. };
  64. /* start of keys that are not directly used by Vim but can be mapped */
  65. #define BT_EXTRA_KEYS 0x101
  66. static struct builtin_term *find_builtin_term __ARGS((char_u *name));
  67. static void parse_builtin_tcap __ARGS((char_u *s));
  68. static void term_color __ARGS((char_u *s, int n));
  69. static void gather_termleader __ARGS((void));
  70. static int get_bytes_from_buf __ARGS((char_u *, char_u *, int));
  71. static int term_is_builtin __ARGS((char_u *));
  72. #ifdef HAVE_TGETENT
  73. static char_u *tgetent_error __ARGS((char_u *, char_u *));
  74. /*
  75.  * Here is our own prototype for tgetstr(), any prototypes from the include
  76.  * files have been disabled by the define at the start of this file.
  77.  */
  78. char *tgetstr __ARGS((char *, char **));
  79. /*
  80.  * Don't declare these variables if termcap.h contains them.
  81.  * Autoconf checks if these variables should be declared extern (not all
  82.  * systems have them).
  83.  * Some versions define ospeed to be speed_t, but that is incompatible with
  84.  * BSD, where ospeed is short and speed_t is long.
  85.  */
  86. # ifndef HAVE_OSPEED
  87. #  ifdef OSPEED_EXTERN
  88. extern short ospeed;
  89. #   else
  90. short ospeed;
  91. #   endif
  92. # endif
  93. # ifndef HAVE_UP_BC_PC
  94. #  ifdef UP_BC_PC_EXTERN
  95. extern char *UP, *BC, PC;
  96. #  else
  97. char *UP, *BC, PC;
  98. #  endif
  99. # endif
  100. # define TGETSTR(s, p) (char_u *)tgetstr((s), (char **)(p))
  101. # define TGETENT(b, t) tgetent((char *)(b), (char *)(t))
  102. #endif /* HAVE_TGETENT */
  103. struct builtin_term builtin_termcaps[] =
  104. {
  105. #if defined(USE_GUI)
  106. /*
  107.  * Motif/Athena pseudo term-cap.
  108.  */
  109.     {(int)KS_NAME, "gui"},
  110.     {(int)KS_CE, "33|$"},
  111.     {(int)KS_AL, "33|i"},
  112. # ifdef TERMINFO
  113.     {(int)KS_CAL, "33|%p1%dI"},
  114. # else
  115.     {(int)KS_CAL, "33|%dI"},
  116. # endif
  117.     {(int)KS_DL, "33|d"},
  118. # ifdef TERMINFO
  119.     {(int)KS_CDL, "33|%p1%dD"},
  120.     {(int)KS_CS, "33|%p1%d;%p2%dR"},
  121. # else
  122.     {(int)KS_CDL, "33|%dD"},
  123.     {(int)KS_CS, "33|%d;%dR"},
  124. # endif
  125.     {(int)KS_CL, "33|C"},
  126.     {(int)KS_ME, "33|31H"}, /* 31 = HL_ALL, H = off */
  127.     {(int)KS_MR, "33|1h"}, /* 1  = HL_INVERSE, h = on */
  128.     {(int)KS_MD, "33|2h"}, /* 2  = HL_BOLD, h = on */
  129.     {(int)KS_SE, "33|16H"}, /* 16 = HL_STANDOUT, H = off */
  130.     {(int)KS_SO, "33|16h"}, /* 16 = HL_STANDOUT, h = on */
  131.     {(int)KS_UE, "33|8H"}, /* 8  = HL_UNDERLINE, H = off */
  132.     {(int)KS_US, "33|8h"}, /* 8  = HL_UNDERLINE, h = on */
  133.     {(int)KS_CZR, "33|4H"}, /* 4  = HL_ITALIC, H = off */
  134.     {(int)KS_CZH, "33|4h"}, /* 4  = HL_ITALIC, h = on */
  135.     {(int)KS_VB, "33|f"},
  136.     {(int)KS_MS, "y"},
  137.     {(int)KS_LE, "10"}, /* cursur-left = BS */
  138.     {(int)KS_ND, "14"}, /* cursor-right = CTRL-L */
  139. # ifdef TERMINFO
  140.     {(int)KS_CM, "33|%p1%d;%p2%dM"},
  141. # else
  142.     {(int)KS_CM, "33|%d;%dM"},
  143. # endif
  144. /* there are no key sequences here, the GUI sequences are recognized
  145.  * in check_termcodes() */
  146. #endif
  147. #ifndef NO_BUILTIN_TCAPS
  148. # if defined(RISCOS) || defined(ALL_BUILTIN_TCAPS)
  149. /*
  150.  * Default for the Acorn.
  151.  */
  152.     {(int)KS_NAME, "riscos"},
  153.     {(int)KS_CL, "14"}, /* Cls and Home Cursor */
  154.     {(int)KS_CM, "01%d01%d02"}, /* Position cursor */
  155.     {(int)KS_CCO, "16"}, /* Allow 16 colors */
  156.     {(int)KS_CAF, "01%d21"}, /* Set foreground colour */
  157.     {(int)KS_CAB, "01%d22"}, /* Set background colour */
  158.     {(int)KS_ME, "04"}, /* Normal mode */
  159.     {(int)KS_MR, "05"}, /* Reverse */
  160.     {(int)KS_VI, "16"}, /* Cursor invisible */
  161.     {(int)KS_VE, "17"}, /* Cursor visible */
  162.     {(int)KS_VS, "18"}, /* Cursor very visible */
  163.     {(int)KS_CS, "01%d01%d03"}, /* Set scroll region */
  164.     {(int)KS_SR, "23"}, /* Scroll text down */
  165.     {K_UP, "217"},
  166.     {K_DOWN, "216"},
  167.     {K_LEFT, "214"},
  168.     {K_RIGHT, "215"},
  169.     {K_S_UP, "237"},
  170.     {K_S_DOWN, "236"},
  171.     {K_S_LEFT, "234"},
  172.     {K_S_RIGHT, "235"},
  173.     {K_F1, "201"},
  174.     {K_F2, "202"},
  175.     {K_F3, "203"},
  176.     {K_F4, "204"},
  177.     {K_F5, "205"},
  178.     {K_F6, "206"},
  179.     {K_F7, "207"},
  180.     {K_F8, "208"},
  181.     {K_F9, "209"},
  182.     {K_F10, "312"},
  183.     {K_F11, "313"},
  184.     {K_F12, "314"},
  185.     {K_S_F1, "221"},
  186.     {K_S_F2, "222"},
  187.     {K_S_F3, "223"},
  188.     {K_S_F4, "224"},
  189.     {K_S_F5, "225"},
  190.     {K_S_F6, "226"},
  191.     {K_S_F7, "227"},
  192.     {K_S_F8, "228"},
  193.     {K_S_F9, "229"},
  194.     {K_S_F10, "332"},
  195.     {K_S_F11, "333"},
  196.     {K_S_F12, "334"},
  197.     {K_BS, "10"},
  198.     {K_INS, "315"},
  199.     {K_DEL, "177"},
  200.     {K_HOME, "36"},
  201.     {K_END, "213"},
  202.     {K_PAGEUP, "237"},
  203.     {K_PAGEDOWN, "236"},
  204. # endif /* Acorn terminal */
  205. # if defined(AMIGA) || defined(ALL_BUILTIN_TCAPS)
  206. /*
  207.  * Amiga console window, default for Amiga
  208.  */
  209.     {(int)KS_NAME, "amiga"},
  210.     {(int)KS_CE, "33[K"},
  211.     {(int)KS_CD, "33[J"},
  212.     {(int)KS_AL, "33[L"},
  213. #  ifdef TERMINFO
  214.     {(int)KS_CAL, "33[%p1%dL"},
  215. #  else
  216.     {(int)KS_CAL, "33[%dL"},
  217. #  endif
  218.     {(int)KS_DL, "33[M"},
  219. #  ifdef TERMINFO
  220.     {(int)KS_CDL, "33[%p1%dM"},
  221. #  else
  222.     {(int)KS_CDL, "33[%dM"},
  223. #  endif
  224.     {(int)KS_CL, "14"},
  225.     {(int)KS_VI, "33[0 p"},
  226.     {(int)KS_VE, "33[1 p"},
  227.     {(int)KS_ME, "33[0m"},
  228.     {(int)KS_MR, "33[7m"},
  229.     {(int)KS_MD, "33[1m"},
  230.     {(int)KS_SE, "33[0m"},
  231.     {(int)KS_SO, "33[33m"},
  232.     {(int)KS_US, "33[4m"},
  233.     {(int)KS_UE, "33[0m"},
  234.     {(int)KS_CZH, "33[3m"},
  235.     {(int)KS_CZR, "33[0m"},
  236.     {(int)KS_MS, "y"},
  237.     {(int)KS_LE, "10"},
  238. #  ifdef TERMINFO
  239.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  240. #  else
  241.     {(int)KS_CM, "33[%i%d;%dH"},
  242. #  endif
  243. #  ifdef TERMINFO
  244.     {(int)KS_CRI, "33[%p1%dC"},
  245. #  else
  246.     {(int)KS_CRI, "33[%dC"},
  247. #  endif
  248.     {K_UP, "233A"},
  249.     {K_DOWN, "233B"},
  250.     {K_LEFT, "233D"},
  251.     {K_RIGHT, "233C"},
  252.     {K_S_UP, "233T"},
  253.     {K_S_DOWN, "233S"},
  254.     {K_S_LEFT, "233 A"},
  255.     {K_S_RIGHT, "233 @"},
  256.     {K_S_TAB, "233Z"},
  257.     {K_F1, "23360~"},/* some compilers don't dig "2330" */
  258.     {K_F2, "23361~"},
  259.     {K_F3, "23362~"},
  260.     {K_F4, "23363~"},
  261.     {K_F5, "23364~"},
  262.     {K_F6, "23365~"},
  263.     {K_F7, "23366~"},
  264.     {K_F8, "23367~"},
  265.     {K_F9, "23370~"},
  266.     {K_F10, "23371~"},
  267.     {K_S_F1, "2336160~"},
  268.     {K_S_F2, "2336161~"},
  269.     {K_S_F3, "2336162~"},
  270.     {K_S_F4, "2336163~"},
  271.     {K_S_F5, "2336164~"},
  272.     {K_S_F6, "2336165~"},
  273.     {K_S_F7, "2336166~"},
  274.     {K_S_F8, "2336167~"},
  275.     {K_S_F9, "2336170~"},
  276.     {K_S_F10, "2336171~"},
  277.     {K_HELP, "233?~"},
  278.     {K_INS, "2336460~"}, /* 101 key keyboard */
  279.     {K_PAGEUP, "2336461~"}, /* 101 key keyboard */
  280.     {K_PAGEDOWN, "2336462~"}, /* 101 key keyboard */
  281.     {K_HOME, "2336464~"}, /* 101 key keyboard */
  282.     {K_END, "2336465~"}, /* 101 key keyboard */
  283.     {BT_EXTRA_KEYS, ""},
  284.     {TERMCAP2KEY('#', '2'), "2336564~"}, /* shifted home key */
  285.     {TERMCAP2KEY('#', '3'), "2336560~"}, /* shifted insert key */
  286.     {TERMCAP2KEY('*', '7'), "2336565~"}, /* shifted end key */
  287. # endif
  288. # if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS)
  289. /*
  290.  * almost standard ANSI terminal, default for bebox
  291.  */
  292.     {(int)KS_NAME, "beos-ansi"},
  293.     {(int)KS_CE, "33[K"},
  294.     {(int)KS_CD, "33[J"},
  295.     {(int)KS_AL, "33[L"},
  296. #  ifdef TERMINFO
  297.     {(int)KS_CAL, "33[%p1%dL"},
  298. #  else
  299.     {(int)KS_CAL, "33[%dL"},
  300. #  endif
  301.     {(int)KS_DL, "33[M"},
  302. #  ifdef TERMINFO
  303.     {(int)KS_CDL, "33[%p1%dM"},
  304. #  else
  305.     {(int)KS_CDL, "33[%dM"},
  306. #  endif
  307. #ifdef BEOS_PR_OR_BETTER
  308. #  ifdef TERMINFO
  309.     {(int)KS_CS, "33[%i%p1%d;%p2%dr"},
  310. #  else
  311.     {(int)KS_CS, "33[%i%d;%dr"}, /* scroll region */
  312. #  endif
  313. #endif
  314.     {(int)KS_CL, "33[H33[2J"},
  315. #ifdef notyet
  316.     {(int)KS_VI, "[VI]"}, /* cursor invisible, VT320: CSI ? 25 l */
  317.     {(int)KS_VE, "[VE]"}, /* cursor visible, VT320: CSI ? 25 h */
  318. #endif
  319.     {(int)KS_ME, "33[m"}, /* normal mode */
  320.     {(int)KS_MR, "33[7m"}, /* reverse */
  321.     {(int)KS_MD, "33[1m"}, /* bold */
  322.     {(int)KS_SO, "33[31m"}, /* standout mode: red */
  323.     {(int)KS_SE, "33[m"}, /* standout end */
  324.     {(int)KS_CZH, "33[35m"}, /* italic: purple */
  325.     {(int)KS_CZR, "33[m"}, /* italic end */
  326.     {(int)KS_US, "33[4m"}, /* underscore mode */
  327.     {(int)KS_UE, "33[m"}, /* underscore end */
  328.     {(int)KS_CCO, "8"}, /* allow 8 colors */
  329. #  ifdef TERMINFO
  330.     {(int)KS_CAB, "33[4%p1%dm"},/* set background color */
  331.     {(int)KS_CAF, "33[3%p1%dm"},/* set foreground color */
  332. #  else
  333.     {(int)KS_CAB, "33[4%dm"}, /* set background color */
  334.     {(int)KS_CAF, "33[3%dm"}, /* set foreground color */
  335. #  endif
  336.     {(int)KS_OP, "33[m"}, /* reset colors */
  337.     {(int)KS_MS, "y"}, /* safe to move cur in reverse mode */
  338.     {(int)KS_LE, "10"},
  339. #  ifdef TERMINFO
  340.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  341. #  else
  342.     {(int)KS_CM, "33[%i%d;%dH"},
  343. #  endif
  344.     {(int)KS_SR, "33M"},
  345. #  ifdef TERMINFO
  346.     {(int)KS_CRI, "33[%p1%dC"},
  347. #  else
  348.     {(int)KS_CRI, "33[%dC"},
  349. #  endif
  350. #if defined(BEOS_DR8)
  351.     {(int)KS_DB, ""}, /* hack! see screen.c */
  352. #endif
  353.     {K_UP, "33[A"},
  354.     {K_DOWN, "33[B"},
  355.     {K_LEFT, "33[D"},
  356.     {K_RIGHT, "33[C"},
  357. # endif
  358. # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
  359. /*
  360.  * standard ANSI terminal, default for unix
  361.  */
  362.     {(int)KS_NAME, "ansi"},
  363.     {(int)KS_CE, "33[K"},
  364.     {(int)KS_AL, "33[L"},
  365. #  ifdef TERMINFO
  366.     {(int)KS_CAL, "33[%p1%dL"},
  367. #  else
  368.     {(int)KS_CAL, "33[%dL"},
  369. #  endif
  370.     {(int)KS_DL, "33[M"},
  371. #  ifdef TERMINFO
  372.     {(int)KS_CDL, "33[%p1%dM"},
  373. #  else
  374.     {(int)KS_CDL, "33[%dM"},
  375. #  endif
  376.     {(int)KS_CL, "33[H33[2J"},
  377.     {(int)KS_ME, "33[0m"},
  378.     {(int)KS_MR, "33[7m"},
  379.     {(int)KS_MS, "y"},
  380.     {(int)KS_LE, "10"},
  381. #  ifdef TERMINFO
  382.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  383. #  else
  384.     {(int)KS_CM, "33[%i%d;%dH"},
  385. #  endif
  386. #  ifdef TERMINFO
  387.     {(int)KS_CRI, "33[%p1%dC"},
  388. #  else
  389.     {(int)KS_CRI, "33[%dC"},
  390. #  endif
  391. # endif
  392. # if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
  393. /*
  394.  * These codes are valid when nansi.sys or equivalent has been installed.
  395.  * Function keys on a PC are preceded with a NUL. These are converted into
  396.  * K_NUL '316' in mch_inchar(), because we cannot handle NULs in key codes.
  397.  * CTRL-arrow is used instead of SHIFT-arrow.
  398.  */
  399. #ifdef __EMX__
  400.     {(int)KS_NAME, "os2ansi"},
  401. #else
  402.     {(int)KS_NAME, "pcansi"},
  403.     {(int)KS_DL, "33[M"},
  404.     {(int)KS_AL, "33[L"},
  405. #endif
  406.     {(int)KS_CE, "33[K"},
  407.     {(int)KS_CL, "33[2J"},
  408.     {(int)KS_ME, "33[0m"},
  409.     {(int)KS_MR, "33[5m"}, /* reverse: black on lightgrey */
  410.     {(int)KS_MD, "33[1m"}, /* bold: white text */
  411.     {(int)KS_SE, "33[0m"}, /* standout end */
  412.     {(int)KS_SO, "33[31m"}, /* standout: white on blue */
  413.     {(int)KS_CZH, "33[34;43m"}, /* italic mode: blue text on yellow */
  414.     {(int)KS_CZR, "33[0m"}, /* italic mode end */
  415.     {(int)KS_US, "33[36;41m"}, /* underscore mode: cyan text on red */
  416.     {(int)KS_UE, "33[0m"}, /* underscore mode end */
  417.     {(int)KS_CCO, "8"}, /* allow 8 colors */
  418. #  ifdef TERMINFO
  419.     {(int)KS_CAB, "33[4%p1%dm"},/* set background color */
  420.     {(int)KS_CAF, "33[3%p1%dm"},/* set foreground color */
  421. #  else
  422.     {(int)KS_CAB, "33[4%dm"}, /* set background color */
  423.     {(int)KS_CAF, "33[3%dm"}, /* set foreground color */
  424. #  endif
  425.     {(int)KS_OP, "33[0m"}, /* reset colors */
  426.     {(int)KS_MS, "y"},
  427.     {(int)KS_LE, "10"},
  428. #  ifdef TERMINFO
  429.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  430. #  else
  431.     {(int)KS_CM, "33[%i%d;%dH"},
  432. #  endif
  433. #  ifdef TERMINFO
  434.     {(int)KS_CRI, "33[%p1%dC"},
  435. #  else
  436.     {(int)KS_CRI, "33[%dC"},
  437. #  endif
  438.     {K_UP, "316H"},
  439.     {K_DOWN, "316P"},
  440.     {K_LEFT, "316K"},
  441.     {K_RIGHT, "316M"},
  442.     {K_S_LEFT, "316s"},
  443.     {K_S_RIGHT, "316t"},
  444.     {K_F1, "316;"},
  445.     {K_F2, "316<"},
  446.     {K_F3, "316="},
  447.     {K_F4, "316>"},
  448.     {K_F5, "316?"},
  449.     {K_F6, "316@"},
  450.     {K_F7, "316A"},
  451.     {K_F8, "316B"},
  452.     {K_F9, "316C"},
  453.     {K_F10, "316D"},
  454.     {K_F11, "316205"}, /* guessed */
  455.     {K_F12, "316206"}, /* guessed */
  456.     {K_S_F1, "316T"},
  457.     {K_S_F2, "316U"},
  458.     {K_S_F3, "316V"},
  459.     {K_S_F4, "316W"},
  460.     {K_S_F5, "316X"},
  461.     {K_S_F6, "316Y"},
  462.     {K_S_F7, "316Z"},
  463.     {K_S_F8, "316["},
  464.     {K_S_F9, "316\"},
  465.     {K_S_F10, "316]"},
  466.     {K_S_F11, "316207"}, /* guessed */
  467.     {K_S_F12, "316210"}, /* guessed */
  468.     {K_INS, "316R"},
  469.     {K_DEL, "316S"},
  470.     {K_HOME, "316G"},
  471.     {K_END, "316O"},
  472.     {K_PAGEDOWN, "316Q"},
  473.     {K_PAGEUP, "316I"},
  474. # endif
  475. # if defined(MSDOS)
  476. /*
  477.  * These codes are valid for the pc video.  The entries that start with ESC |
  478.  * are translated into conio calls in os_msdos.c. Default for MSDOS.
  479.  */
  480.     {(int)KS_NAME, "pcterm"},
  481.     {(int)KS_CE, "33|K"},
  482.     {(int)KS_AL, "33|L"},
  483.     {(int)KS_DL, "33|M"},
  484. #  ifdef TERMINFO
  485.     {(int)KS_CS, "33|%i%p1%d;%p2%dr"},
  486. #  else
  487.     {(int)KS_CS, "33|%i%d;%dr"},
  488. #  endif
  489.     {(int)KS_CL, "33|J"},
  490.     {(int)KS_ME, "33|0m"}, /* normal */
  491.     {(int)KS_MR, "33|112m"}, /* reverse: black on lightgrey */
  492.     {(int)KS_MD, "33|15m"}, /* bold: white text */
  493.     {(int)KS_SE, "33|0m"}, /* standout end */
  494.     {(int)KS_SO, "33|31m"}, /* standout: white on blue */
  495.     {(int)KS_CZH, "33|225m"}, /* italic mode: blue text on yellow */
  496.     {(int)KS_CZR, "33|0m"}, /* italic mode end */
  497.     {(int)KS_US, "33|67m"}, /* underscore mode: cyan text on red */
  498.     {(int)KS_UE, "33|0m"}, /* underscore mode end */
  499.     {(int)KS_CCO, "16"}, /* allow 16 colors */
  500. #  ifdef TERMINFO
  501.     {(int)KS_CAB, "33|%p1%db"}, /* set background color */
  502.     {(int)KS_CAF, "33|%p1%df"}, /* set foreground color */
  503. #  else
  504.     {(int)KS_CAB, "33|%db"}, /* set background color */
  505.     {(int)KS_CAF, "33|%df"}, /* set foreground color */
  506. #  endif
  507.     {(int)KS_MS, "y"},
  508.     {(int)KS_LE, "10"},
  509. #  ifdef TERMINFO
  510.     {(int)KS_CM, "33|%i%p1%d;%p2%dH"},
  511. #  else
  512.     {(int)KS_CM, "33|%i%d;%dH"},
  513. #  endif
  514. #ifdef DJGPP
  515.     {(int)KS_VB, "33|B"}, /* visual bell */
  516. #endif
  517.     {K_UP, "316H"},
  518.     {K_DOWN, "316P"},
  519.     {K_LEFT, "316K"},
  520.     {K_RIGHT, "316M"},
  521.     {K_S_LEFT, "316s"},
  522.     {K_S_RIGHT, "316t"},
  523.     {K_S_TAB, "31617"},
  524.     {K_F1, "316;"},
  525.     {K_F2, "316<"},
  526.     {K_F3, "316="},
  527.     {K_F4, "316>"},
  528.     {K_F5, "316?"},
  529.     {K_F6, "316@"},
  530.     {K_F7, "316A"},
  531.     {K_F8, "316B"},
  532.     {K_F9, "316C"},
  533.     {K_F10, "316D"},
  534.     {K_F11, "316205"}, /* only when nobioskey */
  535.     {K_F12, "316206"}, /* only when nobioskey */
  536.     {K_S_F1, "316T"},
  537.     {K_S_F2, "316U"},
  538.     {K_S_F3, "316V"},
  539.     {K_S_F4, "316W"},
  540.     {K_S_F5, "316X"},
  541.     {K_S_F6, "316Y"},
  542.     {K_S_F7, "316Z"},
  543.     {K_S_F8, "316["},
  544.     {K_S_F9, "316\"},
  545.     {K_S_F10, "316]"},
  546.     {K_S_F11, "316207"}, /* only when nobioskey */
  547.     {K_S_F12, "316210"}, /* only when nobioskey */
  548.     {K_INS, "316R"},
  549.     {K_DEL, "316S"},
  550.     {K_HOME, "316G"},
  551.     {K_END, "316O"},
  552.     {K_PAGEDOWN, "316Q"},
  553.     {K_PAGEUP, "316I"},
  554. # endif
  555. # if defined(WIN32) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
  556. /*
  557.  * These codes are valid for the Win32 Console .  The entries that start with
  558.  * ESC | are translated into console calls in os_win32.c.  The function keys
  559.  * are also translated in os_win32.c.
  560.  */
  561.     {(int)KS_NAME, "win32"},
  562.     {(int)KS_CE, "33|K"}, /* clear to end of line */
  563.     {(int)KS_AL, "33|L"}, /* add new blank line */
  564. #  ifdef TERMINFO
  565.     {(int)KS_CAL, "33|%p1%dL"}, /* add number of new blank lines */
  566. #  else
  567.     {(int)KS_CAL, "33|%dL"}, /* add number of new blank lines */
  568. #  endif
  569.     {(int)KS_DL, "33|M"}, /* delete line */
  570. #  ifdef TERMINFO
  571.     {(int)KS_CDL, "33|%p1%dM"}, /* delete number of lines */
  572. #  else
  573.     {(int)KS_CDL, "33|%dM"}, /* delete number of lines */
  574. #  endif
  575.     {(int)KS_CL, "33|J"}, /* clear screen */
  576.     {(int)KS_CD, "33|j"}, /* clear to end of display */
  577.     {(int)KS_VI, "33|v"}, /* cursor invisible */
  578.     {(int)KS_VE, "33|V"}, /* cursor visible */
  579.     {(int)KS_ME, "33|0m"}, /* normal */
  580.     {(int)KS_MR, "33|112m"}, /* reverse: black on lightgray */
  581.     {(int)KS_MD, "33|15m"}, /* bold: white on black */
  582. #if 1
  583.     {(int)KS_SO, "33|31m"}, /* standout: white on blue */
  584.     {(int)KS_SE, "33|0m"}, /* standout end */
  585. #else
  586.     {(int)KS_SO, "33|F"}, /* standout: high intensity */
  587.     {(int)KS_SE, "33|f"}, /* standout end */
  588. #endif
  589.     {(int)KS_CZH, "33|225m"}, /* italic: blue text on yellow */
  590.     {(int)KS_CZR, "33|0m"}, /* italic end */
  591.     {(int)KS_US, "33|67m"}, /* underscore: cyan text on red */
  592.     {(int)KS_UE, "33|0m"}, /* underscore end */
  593.     {(int)KS_CCO, "16"}, /* allow 16 colors */
  594. #  ifdef TERMINFO
  595.     {(int)KS_CAB, "33|%p1%db"}, /* set background color */
  596.     {(int)KS_CAF, "33|%p1%df"}, /* set foreground color */
  597. #  else
  598.     {(int)KS_CAB, "33|%db"}, /* set background color */
  599.     {(int)KS_CAF, "33|%df"}, /* set foreground color */
  600. #  endif
  601.     {(int)KS_MS, "y"}, /* save to move cur in reverse mode */
  602.     {(int)KS_LE, "10"},
  603. #  ifdef TERMINFO
  604.     {(int)KS_CM, "33|%i%p1%d;%p2%dH"},/* cursor motion */
  605. #  else
  606.     {(int)KS_CM, "33|%i%d;%dH"},/* cursor motion */
  607. #  endif
  608.     {(int)KS_VB, "33|B"}, /* visual bell */
  609.     {(int)KS_TI, "33|S"}, /* put terminal in termcap mode */
  610.     {(int)KS_TE, "33|E"}, /* out of termcap mode */
  611.     {(int)KS_CS, "33|%i%d;%dr"},/* scroll region */
  612.     {K_UP, "316H"},
  613.     {K_DOWN, "316P"},
  614.     {K_LEFT, "316K"},
  615.     {K_RIGHT, "316M"},
  616.     {K_S_UP, "316304"},
  617.     {K_S_DOWN, "316317"},
  618.     {K_S_LEFT, "316311"},
  619.     {K_S_RIGHT, "316313"},
  620.     {K_S_TAB, "31617"},
  621.     {K_F1, "316;"},
  622.     {K_F2, "316<"},
  623.     {K_F3, "316="},
  624.     {K_F4, "316>"},
  625.     {K_F5, "316?"},
  626.     {K_F6, "316@"},
  627.     {K_F7, "316A"},
  628.     {K_F8, "316B"},
  629.     {K_F9, "316C"},
  630.     {K_F10, "316D"},
  631.     {K_F11, "316205"},
  632.     {K_F12, "316206"},
  633.     {K_S_F1, "316T"},
  634.     {K_S_F2, "316U"},
  635.     {K_S_F3, "316V"},
  636.     {K_S_F4, "316W"},
  637.     {K_S_F5, "316X"},
  638.     {K_S_F6, "316Y"},
  639.     {K_S_F7, "316Z"},
  640.     {K_S_F8, "316["},
  641.     {K_S_F9, "316\"},
  642.     {K_S_F10, "316]"},
  643.     {K_S_F11, "316207"},
  644.     {K_S_F12, "316210"},
  645.     {K_INS, "316R"},
  646.     {K_DEL, "316S"},
  647.     {K_HOME, "316G"},
  648.     {K_END, "316O"},
  649.     {K_PAGEDOWN, "316Q"},
  650.     {K_PAGEUP, "316I"},
  651. # endif
  652. # if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__)
  653. /*
  654.  * Ordinary vt52
  655.  */
  656.     {(int)KS_NAME, "vt52"},
  657.     {(int)KS_CE, "33K"},
  658.     {(int)KS_CD, "33J"},
  659.     {(int)KS_CM, "33Y%+ %+ "},
  660.     {(int)KS_LE, "10"},
  661. #  ifdef __MINT__
  662.     {(int)KS_AL, "33L"},
  663.     {(int)KS_DL, "33M"},
  664.     {(int)KS_CL, "33E"},
  665.     {(int)KS_SR, "33I"},
  666.     {(int)KS_VE, "33e"},
  667.     {(int)KS_VI, "33f"},
  668.     {(int)KS_SO, "33p"},
  669.     {(int)KS_SE, "33q"},
  670.     {K_UP, "33A"},
  671.     {K_DOWN, "33B"},
  672.     {K_LEFT, "33D"},
  673.     {K_RIGHT, "33C"},
  674.     {K_S_UP, "33a"},
  675.     {K_S_DOWN, "33b"},
  676.     {K_S_LEFT, "33d"},
  677.     {K_S_RIGHT, "33c"},
  678.     {K_F1, "33P"},
  679.     {K_F2, "33Q"},
  680.     {K_F3, "33R"},
  681.     {K_F4, "33S"},
  682.     {K_F5, "33T"},
  683.     {K_F6, "33U"},
  684.     {K_F7, "33V"},
  685.     {K_F8, "33W"},
  686.     {K_F9, "33X"},
  687.     {K_F10, "33Y"},
  688.     {K_S_F1, "33p"},
  689.     {K_S_F2, "33q"},
  690.     {K_S_F3, "33r"},
  691.     {K_S_F4, "33s"},
  692.     {K_S_F5, "33t"},
  693.     {K_S_F6, "33u"},
  694.     {K_S_F7, "33v"},
  695.     {K_S_F8, "33w"},
  696.     {K_S_F9, "33x"},
  697.     {K_S_F10, "33y"},
  698.     {K_INS, "33I"},
  699.     {K_HOME, "33E"},
  700.     {K_PAGEDOWN, "33b"},
  701.     {K_PAGEUP, "33a"},
  702. #  else
  703.     {(int)KS_AL, "33T"},
  704.     {(int)KS_DL, "33U"},
  705.     {(int)KS_CL, "33H33J"},
  706.     {(int)KS_ME, "33SO"},
  707.     {(int)KS_MR, "33S2"},
  708.     {(int)KS_MS, "y"},
  709. #  endif
  710. # endif
  711. # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
  712. /*
  713.  * The xterm termcap is missing F14 and F15, because they send the same
  714.  * codes as the undo and help key, although they don't work on all keyboards.
  715.  */
  716.     {(int)KS_NAME, "xterm"},
  717.     {(int)KS_CE, "33[K"},
  718.     {(int)KS_AL, "33[L"},
  719. #  ifdef TERMINFO
  720.     {(int)KS_CAL, "33[%p1%dL"},
  721. #  else
  722.     {(int)KS_CAL, "33[%dL"},
  723. #  endif
  724.     {(int)KS_DL, "33[M"},
  725. #  ifdef TERMINFO
  726.     {(int)KS_CDL, "33[%p1%dM"},
  727. #  else
  728.     {(int)KS_CDL, "33[%dM"},
  729. #  endif
  730. #  ifdef TERMINFO
  731.     {(int)KS_CS, "33[%i%p1%d;%p2%dr"},
  732. #  else
  733.     {(int)KS_CS, "33[%i%d;%dr"},
  734. #  endif
  735.     {(int)KS_CL, "33[H33[2J"},
  736.     {(int)KS_CD, "33[J"},
  737.     {(int)KS_ME, "33[m"},
  738.     {(int)KS_MR, "33[7m"},
  739.     {(int)KS_MD, "33[1m"},
  740.     {(int)KS_UE, "33[m"},
  741.     {(int)KS_US, "33[4m"},
  742.     {(int)KS_MS, "y"},
  743.     {(int)KS_LE, "10"},
  744. #  ifdef TERMINFO
  745.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  746. #  else
  747.     {(int)KS_CM, "33[%i%d;%dH"},
  748. #  endif
  749.     {(int)KS_SR, "33M"},
  750. #  ifdef TERMINFO
  751.     {(int)KS_CRI, "33[%p1%dC"},
  752. #  else
  753.     {(int)KS_CRI, "33[%dC"},
  754. #  endif
  755.     {(int)KS_KS, "33[?1h33="},
  756.     {(int)KS_KE, "33[?1l33>"},
  757. #  ifdef SAVE_XTERM_SCREEN
  758.     {(int)KS_TI, "33733[?47h"},
  759.     {(int)KS_TE, "33[2J33[?47l338"},
  760. #  endif
  761.     {K_UP, "33OA"},
  762.     {K_DOWN, "33OB"},
  763.     {K_LEFT, "33OD"},
  764.     {K_RIGHT, "33OC"},
  765.     {K_S_UP, "33Ox"},
  766.     {K_S_DOWN, "33Or"},
  767.     {K_S_LEFT, "33Ot"},
  768.     {K_S_RIGHT, "33Ov"},
  769.     /* An extra set of function keys for vt100 mode */
  770.     {K_XF1, "33OP"},
  771.     {K_XF2, "33OQ"},
  772.     {K_XF3, "33OR"},
  773.     {K_XF4, "33OS"},
  774.     {K_F1, "33[11~"},
  775.     {K_F2, "33[12~"},
  776.     {K_F3, "33[13~"},
  777.     {K_F4, "33[14~"},
  778.     {K_F5, "33[15~"},
  779.     {K_F6, "33[17~"},
  780.     {K_F7, "33[18~"},
  781.     {K_F8, "33[19~"},
  782.     {K_F9, "33[20~"},
  783.     {K_F10, "33[21~"},
  784.     {K_F11, "33[23~"},
  785.     {K_F12, "33[24~"},
  786.     {K_HELP, "33[28~"},
  787.     {K_UNDO, "33[26~"},
  788.     {K_INS, "33[2~"},
  789.     {K_HOME, "33[7~"},
  790.     {K_KHOME, "33[1~"},
  791.     {K_END, "33[8~"},
  792.     {K_KEND, "33[4~"},
  793.     {K_PAGEUP, "33[5~"},
  794.     {K_PAGEDOWN, "33[6~"},
  795.     {K_KPLUS, "33Ok"}, /* keypad plus */
  796.     {K_KMINUS, "33Om"}, /* keypad minus */
  797.     {K_KDIVIDE, "33Oo"}, /* keypad / */
  798.     {K_KMULTIPLY, "33Oj"}, /* keypad * */
  799.     {K_KENTER, "33OM"}, /* keypad Enter */
  800.     /* {K_DEL, "33[3~"}, not used */
  801.     {BT_EXTRA_KEYS,   ""},
  802.     {TERMCAP2KEY('k', '0'), "33[10~"}, /* F0 */
  803.     {TERMCAP2KEY('F', '3'), "33[25~"}, /* F13 */
  804.     {TERMCAP2KEY('F', '6'), "33[29~"}, /* F16 */
  805.     {TERMCAP2KEY('F', '7'), "33[31~"}, /* F17 */
  806.     {TERMCAP2KEY('F', '8'), "33[32~"}, /* F18 */
  807.     {TERMCAP2KEY('F', '9'), "33[33~"}, /* F19 */
  808.     {TERMCAP2KEY('F', 'A'), "33[34~"}, /* F20 */
  809. # endif
  810. # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS)
  811. /*
  812.  * iris-ansi for Silicon Graphics machines.
  813.  */
  814.     {(int)KS_NAME, "iris-ansi"},
  815.     {(int)KS_CE, "33[K"},
  816.     {(int)KS_CD, "33[J"},
  817.     {(int)KS_AL, "33[L"},
  818. #  ifdef TERMINFO
  819.     {(int)KS_CAL, "33[%p1%dL"},
  820. #  else
  821.     {(int)KS_CAL, "33[%dL"},
  822. #  endif
  823.     {(int)KS_DL, "33[M"},
  824. #  ifdef TERMINFO
  825.     {(int)KS_CDL, "33[%p1%dM"},
  826. #  else
  827.     {(int)KS_CDL, "33[%dM"},
  828. #  endif
  829. /*
  830.  * This "cs" is not working correctly. What is the right one?
  831.  */
  832. #if 0
  833. #  ifdef TERMINFO
  834.     {(int)KS_CS, "33[%i%p1%d;%p2%dr"},
  835. #  else
  836.      {(int)KS_CS, "33[%i%d;%dr"},
  837. #  endif
  838. #endif
  839.     {(int)KS_CL, "33[H33[2J"},
  840.     {(int)KS_VE, "33[9/y33[12/y33[=6l"},
  841.     {(int)KS_VS, "33[10/y33[=1h33[=2l33[=6h"},
  842.     {(int)KS_SE, "33[m"},
  843.     {(int)KS_SO, "33[1;7m"},
  844.     {(int)KS_ME, "33[m"},
  845.     {(int)KS_MR, "33[7m"},
  846.     {(int)KS_MD, "33[1m"},
  847.     {(int)KS_UE, "33[m"},
  848.     {(int)KS_US, "33[4m"},
  849.     {(int)KS_MS, "y"}, /* does this really work? */
  850.     {(int)KS_LE, "10"},
  851. #  ifdef TERMINFO
  852.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  853. #  else
  854.     {(int)KS_CM, "33[%i%d;%dH"},
  855. #  endif
  856.     {(int)KS_SR, "33M"},
  857. #  ifdef TERMINFO
  858.     {(int)KS_CRI, "33[%p1%dC"},
  859. #  else
  860.     {(int)KS_CRI, "33[%dC"},
  861. #  endif
  862.     {K_UP, "33[A"},
  863.     {K_DOWN, "33[B"},
  864.     {K_LEFT, "33[D"},
  865.     {K_RIGHT, "33[C"},
  866.     {K_S_UP, "33[161q"},
  867.     {K_S_DOWN, "33[164q"},
  868.     {K_S_LEFT, "33[158q"},
  869.     {K_S_RIGHT, "33[167q"},
  870.     {K_F1, "33[001q"},
  871.     {K_F2, "33[002q"},
  872.     {K_F3, "33[003q"},
  873.     {K_F4, "33[004q"},
  874.     {K_F5, "33[005q"},
  875.     {K_F6, "33[006q"},
  876.     {K_F7, "33[007q"},
  877.     {K_F8, "33[008q"},
  878.     {K_F9, "33[009q"},
  879.     {K_F10, "33[010q"},
  880.     {K_F11, "33[011q"},
  881.     {K_F12, "33[012q"},
  882.     {K_S_F1, "33[013q"},
  883.     {K_S_F2, "33[014q"},
  884.     {K_S_F3, "33[015q"},
  885.     {K_S_F4, "33[016q"},
  886.     {K_S_F5, "33[017q"},
  887.     {K_S_F6, "33[018q"},
  888.     {K_S_F7, "33[019q"},
  889.     {K_S_F8, "33[020q"},
  890.     {K_S_F9, "33[021q"},
  891.     {K_S_F10, "33[022q"},
  892.     {K_S_F11, "33[023q"},
  893.     {K_S_F12, "33[024q"},
  894.     {K_INS, "33[139q"},
  895.     {K_HOME, "33[H"},
  896.     {K_END, "33[146q"},
  897.     {K_PAGEUP, "33[150q"},
  898.     {K_PAGEDOWN, "33[154q"},
  899. # endif
  900. # if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
  901. /*
  902.  * for debugging
  903.  */
  904.     {(int)KS_NAME, "debug"},
  905.     {(int)KS_CE, "[CE]"},
  906.     {(int)KS_CD, "[CD]"},
  907.     {(int)KS_AL, "[AL]"},
  908. #  ifdef TERMINFO
  909.     {(int)KS_CAL, "[CAL%p1%d]"},
  910. #  else
  911.     {(int)KS_CAL, "[CAL%d]"},
  912. #  endif
  913.     {(int)KS_DL, "[DL]"},
  914. #  ifdef TERMINFO
  915.     {(int)KS_CDL, "[CDL%p1%d]"},
  916. #  else
  917.     {(int)KS_CDL, "[CDL%d]"},
  918. #  endif
  919. #  ifdef TERMINFO
  920.     {(int)KS_CS, "[%dCS%p1%d]"},
  921. #  else
  922.     {(int)KS_CS, "[%dCS%d]"},
  923. #  endif
  924. #  ifdef TERMINFO
  925.     {(int)KS_CAB, "[CAB%p1%d]"},
  926.     {(int)KS_CAF, "[CAF%p1%d]"},
  927.     {(int)KS_CSB, "[CSB%p1%d]"},
  928.     {(int)KS_CSF, "[CSF%p1%d]"},
  929. #  else
  930.     {(int)KS_CAB, "[CAB%d]"},
  931.     {(int)KS_CAF, "[CAF%d]"},
  932.     {(int)KS_CSB, "[CSB%d]"},
  933.     {(int)KS_CSF, "[CSF%d]"},
  934. #  endif
  935.     {(int)KS_OP, "[OP]"},
  936.     {(int)KS_LE, "[LE]"},
  937.     {(int)KS_CL, "[CL]"},
  938.     {(int)KS_VI, "[VI]"},
  939.     {(int)KS_VE, "[VE]"},
  940.     {(int)KS_VS, "[VS]"},
  941.     {(int)KS_ME, "[ME]"},
  942.     {(int)KS_MR, "[MR]"},
  943.     {(int)KS_MB, "[MB]"},
  944.     {(int)KS_MD, "[MD]"},
  945.     {(int)KS_SE, "[SE]"},
  946.     {(int)KS_SO, "[SO]"},
  947.     {(int)KS_UE, "[UE]"},
  948.     {(int)KS_US, "[US]"},
  949.     {(int)KS_MS, "[MS]"},
  950. #  ifdef TERMINFO
  951.     {(int)KS_CM, "[%p1%dCM%p2%d]"},
  952. #  else
  953.     {(int)KS_CM, "[%dCM%d]"},
  954. #  endif
  955.     {(int)KS_SR, "[SR]"},
  956. #  ifdef TERMINFO
  957.     {(int)KS_CRI, "[CRI%p1%d]"},
  958. #  else
  959.     {(int)KS_CRI, "[CRI%d]"},
  960. #  endif
  961.     {(int)KS_VB, "[VB]"},
  962.     {(int)KS_KS, "[KS]"},
  963.     {(int)KS_KE, "[KE]"},
  964.     {(int)KS_TI, "[TI]"},
  965.     {(int)KS_TE, "[TE]"},
  966.     {K_UP, "[KU]"},
  967.     {K_DOWN, "[KD]"},
  968.     {K_LEFT, "[KL]"},
  969.     {K_RIGHT, "[KR]"},
  970.     {K_S_UP, "[S-KU]"},
  971.     {K_S_DOWN, "[S-KD]"},
  972.     {K_S_LEFT, "[S-KL]"},
  973.     {K_S_RIGHT, "[S-KR]"},
  974.     {K_F1, "[F1]"},
  975.     {K_F2, "[F2]"},
  976.     {K_F3, "[F3]"},
  977.     {K_F4, "[F4]"},
  978.     {K_F5, "[F5]"},
  979.     {K_F6, "[F6]"},
  980.     {K_F7, "[F7]"},
  981.     {K_F8, "[F8]"},
  982.     {K_F9, "[F9]"},
  983.     {K_F10, "[F10]"},
  984.     {K_F11, "[F11]"},
  985.     {K_F12, "[F12]"},
  986.     {K_S_F1, "[S-F1]"},
  987.     {K_S_F2, "[S-F2]"},
  988.     {K_S_F3, "[S-F3]"},
  989.     {K_S_F4, "[S-F4]"},
  990.     {K_S_F5, "[S-F5]"},
  991.     {K_S_F6, "[S-F6]"},
  992.     {K_S_F7, "[S-F7]"},
  993.     {K_S_F8, "[S-F8]"},
  994.     {K_S_F9, "[S-F9]"},
  995.     {K_S_F10, "[S-F10]"},
  996.     {K_S_F11, "[S-F11]"},
  997.     {K_S_F12, "[S-F12]"},
  998.     {K_HELP, "[HELP]"},
  999.     {K_UNDO, "[UNDO]"},
  1000.     {K_BS, "[BS]"},
  1001.     {K_INS, "[INS]"},
  1002.     {K_DEL, "[DEL]"},
  1003.     {K_HOME, "[HOME]"},
  1004.     {K_END, "[END]"},
  1005.     {K_PAGEUP, "[PAGEUP]"},
  1006.     {K_PAGEDOWN, "[PAGEDOWN]"},
  1007.     {K_KHOME, "[KHOME]"},
  1008.     {K_KEND, "[KEND]"},
  1009.     {K_KPAGEUP, "[KPAGEUP]"},
  1010.     {K_KPAGEDOWN, "[KPAGEDOWN]"},
  1011.     {K_MOUSE, "[MOUSE]"},
  1012.     {K_KPLUS, "[KPLUS]"},
  1013.     {K_KMINUS, "[KMINUS]"},
  1014.     {K_KDIVIDE, "[KDIVIDE]"},
  1015.     {K_KMULTIPLY, "[KMULTIPLY]"},
  1016.     {K_KENTER, "[KENTER]"},
  1017. # endif
  1018. #endif /* NO_BUILTIN_TCAPS */
  1019. /*
  1020.  * The most minimal terminal: only clear screen and cursor positioning
  1021.  * Always included.
  1022.  */
  1023.     {(int)KS_NAME, "dumb"},
  1024.     {(int)KS_CL, "14"},
  1025. #ifdef TERMINFO
  1026.     {(int)KS_CM, "33[%i%p1%d;%p2%dH"},
  1027. #else
  1028.     {(int)KS_CM, "33[%i%d;%dH"},
  1029. #endif
  1030. /*
  1031.  * end marker
  1032.  */
  1033.     {(int)KS_NAME, NULL}
  1034. }; /* end of builtin_termcaps */
  1035. /*
  1036.  * DEFAULT_TERM is used, when no terminal is specified with -T option or $TERM.
  1037.  */
  1038. #ifdef RISCOS
  1039. # define DEFAULT_TERM (char_u *)"riscos"
  1040. #endif
  1041. #ifdef AMIGA
  1042. # define DEFAULT_TERM (char_u *)"amiga"
  1043. #endif
  1044. #ifdef WIN32
  1045. # define DEFAULT_TERM (char_u *)"win32"
  1046. #endif
  1047. #ifdef MSDOS
  1048. # define DEFAULT_TERM (char_u *)"pcterm"
  1049. #endif
  1050. #if defined(UNIX) && !defined(__MINT__)
  1051. # define DEFAULT_TERM (char_u *)"ansi"
  1052. #endif
  1053. #ifdef __MINT__
  1054. # define DEFAULT_TERM (char_u *)"vt52"
  1055. #endif
  1056. #ifdef __EMX__
  1057. # define DEFAULT_TERM (char_u *)"os2ansi"
  1058. #endif
  1059. #ifdef VMS
  1060. # define DEFAULT_TERM (char_u *)"ansi"
  1061. #endif
  1062. #ifdef __BEOS__
  1063. # undef DEFAULT_TERM
  1064. # define DEFAULT_TERM (char_u *)"beos-ansi"
  1065. #endif
  1066. #ifdef macintosh
  1067. # define DEFAULT_TERM (char_u *)"mac-ansi"
  1068. #endif
  1069. /*
  1070.  * Term_strings contains currently used terminal output strings.
  1071.  * It is initialized with the default values by parse_builtin_tcap().
  1072.  * The values can be changed by setting the option with the same name.
  1073.  */
  1074. char_u *(term_strings[(int)KS_LAST + 1]);
  1075. static int need_gather = FALSE; /* need to fill termleader[] */
  1076. static char_u termleader[256 + 1]; /* for check_termcode() */
  1077.     static struct builtin_term *
  1078. find_builtin_term(term)
  1079.     char_u *term;
  1080. {
  1081.     struct builtin_term *p;
  1082.     p = builtin_termcaps;
  1083.     while (p->bt_string != NULL)
  1084.     {
  1085. if (p->bt_entry == (int)KS_NAME)
  1086. {
  1087. #ifdef UNIX
  1088.     if (STRCMP(p->bt_string, "iris-ansi") == 0 && vim_is_iris(term))
  1089. return p;
  1090.     else if (STRCMP(p->bt_string, "xterm") == 0 && vim_is_xterm(term))
  1091. return p;
  1092.     else
  1093. #endif
  1094. if (STRCMP(term, p->bt_string) == 0)
  1095.     return p;
  1096. }
  1097. ++p;
  1098.     }
  1099.     return p;
  1100. }
  1101. /*
  1102.  * Parsing of the builtin termcap entries.
  1103.  * Caller should check if 'name' is a valid builtin term.
  1104.  * The terminal's name is not set, as this is already done in termcapinit().
  1105.  */
  1106.     static void
  1107. parse_builtin_tcap(term)
  1108.     char_u  *term;
  1109. {
  1110.     struct builtin_term     *p;
  1111.     char_u     name[2];
  1112.     p = find_builtin_term(term);
  1113.     for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p)
  1114.     {
  1115. if ((int)p->bt_entry < 0x100) /* KS_xx entry */
  1116. {
  1117.     if (term_strings[p->bt_entry] == NULL ||
  1118.     term_strings[p->bt_entry] == empty_option)
  1119. term_strings[p->bt_entry] = (char_u *)p->bt_string;
  1120. }
  1121. else
  1122. {
  1123.     name[0] = KEY2TERMCAP0((int)p->bt_entry);
  1124.     name[1] = KEY2TERMCAP1((int)p->bt_entry);
  1125.     if (find_termcode(name) == NULL)
  1126. add_termcode(name, (char_u *)p->bt_string);
  1127. }
  1128.     }
  1129. }
  1130. /*
  1131.  * Set terminal options for terminal "term".
  1132.  * Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
  1133.  *
  1134.  * While doing this, until ttest(), some options may be NULL, be careful.
  1135.  */
  1136.     int
  1137. set_termname(term)
  1138.     char_u *term;
  1139. {
  1140.     struct builtin_term *termp;
  1141. #ifdef HAVE_TGETENT
  1142.     int builtin_first = p_tbi;
  1143.     int try;
  1144.     int termcap_cleared = FALSE;
  1145.     static char nr_colors[15];     /* string for number of colors */
  1146. #endif
  1147.     int width = 0, height = 0;
  1148.     char_u *error_msg = NULL;
  1149.     char_u *bs_p, *del_p;
  1150.     if (term_is_builtin(term))
  1151.     {
  1152. term += 8;
  1153. #ifdef HAVE_TGETENT
  1154. builtin_first = 1;
  1155. #endif
  1156.     }
  1157. /*
  1158.  * If HAVE_TGETENT is not defined, only the builtin termcap is used, otherwise:
  1159.  *   If builtin_first is TRUE:
  1160.  *     0. try builtin termcap
  1161.  *     1. try external termcap
  1162.  *     2. if both fail default to a builtin terminal
  1163.  *   If builtin_first is FALSE:
  1164.  *     1. try external termcap
  1165.  *     2. try builtin termcap, if both fail default to a builtin terminal
  1166.  */
  1167. #ifdef HAVE_TGETENT
  1168.     for (try = builtin_first ? 0 : 1; try < 3; ++try)
  1169.     {
  1170. /*
  1171.  * Use external termcap
  1172.  */
  1173. if (try == 1)
  1174. {
  1175.     char_u     *p;
  1176.     static char_u   tstrbuf[TBUFSZ];
  1177.     int     i;
  1178.     char_u     tbuf[TBUFSZ];
  1179.     char_u     *tp;
  1180.     static char     *(key_names[]) =
  1181.     {
  1182.     "ku", "kd", "kr", /* "kl" is a special case */
  1183. # ifdef ARCHIE
  1184.     "su", "sd", /* Termcap code made up! */
  1185. # endif
  1186.     "#4", "%i",
  1187.     "k1", "k2", "k3", "k4", "k5", "k6",
  1188.     "k7", "k8", "k9", "k;", "F1", "F2",
  1189.     "%1", "&8", "kb", "kI", "kD", "kh",
  1190.     "@7", "kP", "kN", "K1", "K3", "K4", "K5",
  1191.     NULL
  1192.     };
  1193.     static struct {
  1194.     enum SpecialKey dest; /* index in term_strings[] */
  1195.     char *name;   /* termcap name for string */
  1196.   } string_names[] =
  1197.     { {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
  1198. {KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
  1199. {KS_CL, "cl"}, {KS_CD, "cd"},
  1200. {KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
  1201. {KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
  1202. {KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
  1203. {KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
  1204. {KS_US, "us"}, {KS_CM, "cm"}, {KS_SR, "sr"},
  1205. {KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
  1206. {KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
  1207. {KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
  1208. {KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
  1209. {KS_ND, "nd"}, {KS_OP, "op"},
  1210. {(enum SpecialKey)0, NULL}
  1211.     };
  1212.     /*
  1213.      * If the external termcap does not have a matching entry, try the
  1214.      * builtin ones.
  1215.      */
  1216.     if ((error_msg = tgetent_error(tbuf, term)) == NULL)
  1217.     {
  1218. tp = tstrbuf;
  1219. if (!termcap_cleared)
  1220. {
  1221.     clear_termoptions(); /* clear old options */
  1222.     termcap_cleared = TRUE;
  1223. }
  1224.     /* get output strings */
  1225. for (i = 0; string_names[i].name != NULL; ++i)
  1226. {
  1227.     if (term_str(string_names[i].dest) == NULL
  1228.     || term_str(string_names[i].dest) == empty_option)
  1229. term_str(string_names[i].dest) =
  1230.    TGETSTR(string_names[i].name, &tp);
  1231. }
  1232. if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms"))
  1233.     T_MS = (char_u *)"y";
  1234. if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs"))
  1235.     T_XS = (char_u *)"y";
  1236. if ((T_DB == NULL || T_DB == empty_option) && tgetflag("db"))
  1237.     T_DB = (char_u *)"y";
  1238. if ((T_DA == NULL || T_DA == empty_option) && tgetflag("da"))
  1239.     T_DA = (char_u *)"y";
  1240.     /* get key codes */
  1241. for (i = 0; key_names[i] != NULL; ++i)
  1242. {
  1243.     if (find_termcode((char_u *)key_names[i]) == NULL)
  1244. add_termcode((char_u *)key_names[i],
  1245.   TGETSTR(key_names[i], &tp));
  1246. }
  1247.     /* if cursor-left == backspace, ignore it (televideo 925) */
  1248. if (find_termcode((char_u *)"kl") == NULL)
  1249. {
  1250.     p = TGETSTR("kl", &tp);
  1251.     if (p != NULL && *p != Ctrl('H'))
  1252. add_termcode((char_u *)"kl", p);
  1253. }
  1254. if (height == 0)
  1255.     height = tgetnum("li");
  1256. if (width == 0)
  1257.     width = tgetnum("co");
  1258. /*
  1259.  * Get number of colors.  If non-zero, store as string in
  1260.  * nr_colors[].
  1261.  */
  1262. i = tgetnum("Co");
  1263. if (i > 0)
  1264. {
  1265.     sprintf(nr_colors, "%d", i);
  1266.     T_CCO = (char_u *)nr_colors;
  1267. }
  1268. # ifndef hpux
  1269. BC = (char *)TGETSTR("bc", &tp);
  1270. UP = (char *)TGETSTR("up", &tp);
  1271. p = TGETSTR("pc", &tp);
  1272. if (p)
  1273.     PC = *p;
  1274. # endif /* hpux */
  1275.     }
  1276. }
  1277. else     /* try == 0 || try == 2 */
  1278. #endif /* HAVE_TGETENT */
  1279. /*
  1280.  * Use builtin termcap
  1281.  */
  1282. {
  1283. #ifdef HAVE_TGETENT
  1284.     /*
  1285.      * If builtin termcap was already used, there is no need to search
  1286.      * for the builtin termcap again, quit now.
  1287.      */
  1288.     if (try == 2 && builtin_first && termcap_cleared)
  1289. break;
  1290. #endif
  1291.     /*
  1292.      * search for 'term' in builtin_termcaps[]
  1293.      */
  1294.     termp = find_builtin_term(term);
  1295.     if (termp->bt_string == NULL) /* did not find it */
  1296.     {
  1297. #ifdef HAVE_TGETENT
  1298. /*
  1299.  * If try == 0, first try the external termcap. If that is not
  1300.  * found we'll get back here with try == 2.
  1301.  * If termcap_cleared is set we used the external termcap,
  1302.  * don't complain about not finding the term in the builtin
  1303.  * termcap.
  1304.  */
  1305. if (try == 0) /* try external one */
  1306.     continue;
  1307. if (termcap_cleared) /* found in external termcap */
  1308.     break;
  1309. #endif
  1310. mch_errmsg("rn");
  1311. if (error_msg != NULL)
  1312. {
  1313.     mch_errmsg((char *)error_msg);
  1314.     mch_errmsg("rn");
  1315. }
  1316. mch_errmsg("'");
  1317. mch_errmsg((char *)term);
  1318. mch_errmsg("' not known. Available builtin terminals are:rn");
  1319. for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
  1320.       ++termp)
  1321. {
  1322.     if (termp->bt_entry == (int)KS_NAME)
  1323.     {
  1324. #ifdef HAVE_TGETENT
  1325. mch_errmsg("    builtin_");
  1326. #else
  1327. mch_errmsg("    ");
  1328. #endif
  1329. mch_errmsg(termp->bt_string);
  1330. mch_errmsg("rn");
  1331.     }
  1332. }
  1333. if (!starting) /* when user typed :set term=xxx, quit here */
  1334. {
  1335.     screen_start(); /* don't know where cursor is now */
  1336.     wait_return(TRUE);
  1337.     return FAIL;
  1338. }
  1339. term = DEFAULT_TERM;
  1340. mch_errmsg("defaulting to '");
  1341. mch_errmsg((char *)term);
  1342. mch_errmsg("'rn");
  1343. screen_start(); /* don't know where cursor is now */
  1344. ui_delay(2000L, TRUE);
  1345. set_string_option_direct((char_u *)"term", -1, term, TRUE);
  1346. mch_display_error();
  1347.     }
  1348.     out_flush();
  1349. #ifdef HAVE_TGETENT
  1350.     if (!termcap_cleared)
  1351.     {
  1352. #endif
  1353. clear_termoptions();     /* clear old options */
  1354. #ifdef HAVE_TGETENT
  1355. termcap_cleared = TRUE;
  1356.     }
  1357. #endif
  1358.     parse_builtin_tcap(term);
  1359. #ifdef USE_GUI
  1360.     if (term_is_gui(term))
  1361.     {
  1362. out_flush();
  1363. gui_init();
  1364. #ifdef HAVE_TGETENT
  1365. break; /* don't try using external termcap */
  1366. #endif
  1367.     }
  1368. #endif /* USE_GUI */
  1369. }
  1370. #ifdef HAVE_TGETENT
  1371.     }
  1372. #endif
  1373. /*
  1374.  * special: There is no info in the termcap about whether the cursor
  1375.  * positioning is relative to the start of the screen or to the start of the
  1376.  * scrolling region.  We just guess here. Only msdos pcterm is known to do it
  1377.  * relative.
  1378.  */
  1379.     if (STRCMP(term, "pcterm") == 0)
  1380. T_CCS = (char_u *)"yes";
  1381.     else
  1382. T_CCS = empty_option;
  1383. #ifdef UNIX
  1384. /*
  1385.  * Any "stty" settings override the default for t_kb from the termcap.
  1386.  * This is in os_unix.c, because it depends a lot on the version of unix that
  1387.  * is being used.
  1388.  * Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
  1389.  */
  1390. #ifdef USE_GUI
  1391.     if (!gui.in_use)
  1392. #endif
  1393. get_stty();
  1394. #endif
  1395. /*
  1396.  * If the termcap has no entry for 'bs' and/or 'del' and the ioctl() also
  1397.  * didn't work, use the default CTRL-H
  1398.  * The default for t_kD is DEL, unless t_kb is DEL.
  1399.  * The vim_strsave'd strings are probably lost forever, well it's only two
  1400.  * bytes.  Don't do this when the GUI is active, it uses "t_kb" and "t_kD"
  1401.  * directly.
  1402.  */
  1403. #ifdef USE_GUI
  1404.     if (!gui.in_use)
  1405. #endif
  1406.     {
  1407. bs_p = find_termcode((char_u *)"kb");
  1408. del_p = find_termcode((char_u *)"kD");
  1409. if (bs_p == NULL || *bs_p == NUL)
  1410.     add_termcode((char_u *)"kb", (bs_p = (char_u *)"10"));
  1411. if ((del_p == NULL || *del_p == NUL) &&
  1412.     (bs_p == NULL || *bs_p != '177'))
  1413.     add_termcode((char_u *)"kD", (char_u *)"177");
  1414.     }
  1415. #ifdef USE_MOUSE
  1416. # ifdef UNIX
  1417.     /* for Unix, set the 'ttymouse' option to the type of mouse to be used.
  1418.      * The termcode for the mouse is added as a side effect in option.c */
  1419.     {
  1420. char_u *p;
  1421. p = (char_u *)"";
  1422. #  ifdef NETTERM_MOUSE
  1423. p = (char_u *)"netterm";
  1424. #  endif
  1425. #  ifdef DEC_MOUSE
  1426. p = (char_u *)"dec";
  1427. #  endif
  1428. #  ifdef XTERM_MOUSE
  1429. if (vim_is_xterm(term))
  1430.     p = (char_u *)"xterm";
  1431. #  endif
  1432. set_option_value((char_u *)"ttym", 0L, p);
  1433.     }
  1434. # else
  1435.     set_mouse_termcode(KS_MOUSE, (char_u *)"233M");
  1436. # endif
  1437. #endif /* USE_MOUSE */
  1438. #ifdef USE_SNIFF
  1439.     {
  1440. char_u name[2];
  1441. name[0] = (int)KS_EXTRA;
  1442. name[1] = (int)KE_SNIFF;
  1443. add_termcode(name, (char_u *)"233sniff");
  1444.     }
  1445. #endif
  1446. #if defined(AMIGA) || defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BEOS__) || defined(RISCOS)
  1447. /* DEFAULT_TERM indicates that it is the machine console. */
  1448.     if (STRCMP(term, DEFAULT_TERM))
  1449. term_console = FALSE;
  1450.     else
  1451.     {
  1452. term_console = TRUE;
  1453. # ifdef AMIGA
  1454. win_resize_on(); /* enable window resizing reports */
  1455. # endif
  1456.     }
  1457. #endif
  1458. #ifdef UNIX
  1459. /*
  1460.  * 'ttyfast' is default on for xterm, iris-ansi and a few others.
  1461.  */
  1462.     if (vim_is_fastterm(term))
  1463. p_tf = TRUE;
  1464. #endif
  1465. #if defined(AMIGA) || defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BEOS__) || defined(RISCOS)
  1466. /*
  1467.  * 'ttyfast' is default on Amiga, MSDOS, Win32, BeBox, RISCOS and OS/2 consoles
  1468.  */
  1469.     if (term_console)
  1470. p_tf = TRUE;
  1471. #endif
  1472.     ttest(TRUE); /* make sure we have a valid set of terminal codes */
  1473.     full_screen = TRUE;     /* we can use termcap codes from now on */
  1474.     set_term_defaults();    /* use current values as defaults */
  1475.     /*
  1476.      * Initialize the terminal with the appropriate termcap codes.
  1477.      * Set the mouse and window title if possible.
  1478.      * Don't do this when starting, need to parse the .vimrc first, because it
  1479.      * may redefine t_TI etc.
  1480.      */
  1481.     if (!starting)
  1482.     {
  1483. starttermcap(); /* may change terminal mode */
  1484. #ifdef USE_MOUSE
  1485. setmouse(); /* may start using the mouse */
  1486. #endif
  1487. maketitle(); /* may display window title */
  1488.     }
  1489. /* display initial screen after ttest() checking. jw. */
  1490.     if (width <= 0 || height <= 0)
  1491.     {
  1492. /* termcap failed to report size */
  1493. /* set defaults, in case ui_get_winsize also fails */
  1494. width = 80;
  1495. #if defined MSDOS  ||  defined WIN32
  1496. height = 25;     /* console is often 25 lines */
  1497. #else
  1498. height = 24;     /* most terminals are 24 lines */
  1499. #endif
  1500.     }
  1501.     set_winsize(width, height, FALSE); /* may change Rows */
  1502.     if (!starting)
  1503.     {
  1504. if (scroll_region)
  1505.     scroll_region_reset();     /* In case Rows changed */
  1506. check_map_keycodes(); /* check mappings for terminal codes used */
  1507. #ifdef AUTOCMD
  1508. {
  1509.     BUF *old_curbuf;
  1510.     /*
  1511.      * Execute the TermChanged autocommands for each buffer that is
  1512.      * loaded.
  1513.      */
  1514.     old_curbuf = curbuf;
  1515.     for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
  1516.     {
  1517. if (curbuf->b_ml.ml_mfp != NULL)
  1518.     apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
  1519.       curbuf);
  1520.     }
  1521.     if (buf_valid(old_curbuf))
  1522. curbuf = old_curbuf;
  1523. }
  1524. #endif
  1525.     }
  1526.     return OK;
  1527. }
  1528. #ifdef USE_MOUSE
  1529.     void
  1530. set_mouse_termcode(n, s)
  1531.     int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
  1532.     char_u *s;
  1533. {
  1534.     char_u name[2];
  1535.     name[0] = n;
  1536.     name[1] = K_FILLER;
  1537.     add_termcode(name, s);
  1538. }
  1539. # ifdef UNIX
  1540.     void
  1541. del_mouse_termcode(n)
  1542.     int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
  1543. {
  1544.     char_u name[2];
  1545.     name[0] = n;
  1546.     name[1] = K_FILLER;
  1547.     del_termcode(name);
  1548. }
  1549. # endif
  1550. #endif /* USE_MOUSE */
  1551. #ifdef HAVE_TGETENT
  1552. /*
  1553.  * Call tgetent()
  1554.  * Return error message if it fails, NULL if it's OK.
  1555.  */
  1556.     static char_u *
  1557. tgetent_error(tbuf, term)
  1558.     char_u  *tbuf;
  1559.     char_u  *term;
  1560. {
  1561.     int     i;
  1562.     i = TGETENT(tbuf, term);
  1563.     if (i == -1)
  1564. return (char_u *)"Cannot open termcap file";
  1565.     if (i == 0)
  1566. #ifdef TERMINFO
  1567. return (char_u *)"Terminal entry not found in terminfo";
  1568. #else
  1569. return (char_u *)"Terminal entry not found in termcap";
  1570. #endif
  1571.     return NULL;
  1572. }
  1573. #endif /* HAVE_TGETENT */
  1574. #if defined(HAVE_TGETENT) && (defined(UNIX) || defined(__EMX__))
  1575. /*
  1576.  * Get Columns and Rows from the termcap. Used after a window signal if the
  1577.  * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
  1578.  * and "li" entries never change. But on some systems this works.
  1579.  * Errors while getting the entries are ignored.
  1580.  */
  1581.     void
  1582. getlinecol()
  1583. {
  1584.     char_u     tbuf[TBUFSZ];
  1585.     if (T_NAME != NULL && *T_NAME != NUL && TGETENT(tbuf, T_NAME) > 0)
  1586.     {
  1587. if (Columns == 0)
  1588.     Columns = tgetnum("co");
  1589. if (Rows == 0)
  1590.     Rows = tgetnum("li");
  1591.     }
  1592. }
  1593. #endif /* defined(HAVE_TGETENT) && defined(UNIX) */
  1594. /*
  1595.  * Get a string entry from the termcap and add it to the list of termcodes.
  1596.  * Used for <t_xx> special keys.
  1597.  * Give an error message for failure when not sourcing.
  1598.  * If force given, replace an existing entry.
  1599.  * Return FAIL if the entry was not found, OK if the entry was added.
  1600.  */
  1601.     int
  1602. add_termcap_entry(name, force)
  1603.     char_u  *name;
  1604.     int     force;
  1605. {
  1606.     char_u  *term;
  1607.     int     key;
  1608.     struct builtin_term *termp;
  1609. #ifdef HAVE_TGETENT
  1610.     char_u  *string;
  1611.     int     i;
  1612.     int     builtin_first;
  1613.     char_u  tbuf[TBUFSZ];
  1614.     char_u  tstrbuf[TBUFSZ];
  1615.     char_u  *tp = tstrbuf;
  1616.     char_u  *error_msg = NULL;
  1617. #endif
  1618. /*
  1619.  * If the GUI is running or will start in a moment, we only support the keys
  1620.  * that the GUI can produce.
  1621.  */
  1622. #ifdef USE_GUI
  1623.     if (gui.in_use || gui.starting)
  1624. return gui_mch_haskey(name);
  1625. #endif
  1626.     if (!force && find_termcode(name) != NULL)     /* it's already there */
  1627. return OK;
  1628.     term = T_NAME;
  1629.     if (term == NULL || *term == NUL)     /* 'term' not defined yet */
  1630. return FAIL;
  1631.     if (term_is_builtin(term))     /* name starts with "builtin_" */
  1632.     {
  1633. term += 8;
  1634. #ifdef HAVE_TGETENT
  1635. builtin_first = TRUE;
  1636. #endif
  1637.     }
  1638. #ifdef HAVE_TGETENT
  1639.     else
  1640. builtin_first = p_tbi;
  1641. #endif
  1642. #ifdef HAVE_TGETENT
  1643. /*
  1644.  * We can get the entry from the builtin termcap and from the external one.
  1645.  * If 'ttybuiltin' is on or the terminal name starts with "builtin_", try
  1646.  * builtin termcap first.
  1647.  * If 'ttybuiltin' is off, try external termcap first.
  1648.  */
  1649.     for (i = 0; i < 2; ++i)
  1650.     {
  1651. if (!builtin_first == i)
  1652. #endif
  1653. /*
  1654.  * Search in builtin termcap
  1655.  */
  1656. {
  1657.     termp = find_builtin_term(term);
  1658.     if (termp->bt_string != NULL) /* found it */
  1659.     {
  1660. key = TERMCAP2KEY(name[0], name[1]);
  1661. while (termp->bt_entry != (int)KS_NAME)
  1662. {
  1663.     if ((int)termp->bt_entry == key)
  1664.     {
  1665. add_termcode(name, (char_u *)termp->bt_string);
  1666. return OK;
  1667.     }
  1668.     ++termp;
  1669. }
  1670.     }
  1671. }
  1672. #ifdef HAVE_TGETENT
  1673. else
  1674. /*
  1675.  * Search in external termcap
  1676.  */
  1677. {
  1678.     error_msg = tgetent_error(tbuf, term);
  1679.     if (error_msg == NULL)
  1680.     {
  1681. string = TGETSTR((char *)name, &tp);
  1682. if (string != NULL && *string != NUL)
  1683. {
  1684.     add_termcode(name, string);
  1685.     return OK;
  1686. }
  1687.     }
  1688. }
  1689.     }
  1690. #endif
  1691.     if (sourcing_name == NULL)
  1692.     {
  1693. #ifdef HAVE_TGETENT
  1694. if (error_msg != NULL)
  1695.     EMSG(error_msg);
  1696. else
  1697. #endif
  1698.     EMSG2("No "%s" entry in termcap", name);
  1699.     }
  1700.     return FAIL;
  1701. }
  1702.     static int
  1703. term_is_builtin(name)
  1704.     char_u  *name;
  1705. {
  1706.     return (STRNCMP(name, "builtin_", (size_t)8) == 0);
  1707. }
  1708. #ifdef USE_GUI
  1709.     int
  1710. term_is_gui(name)
  1711.     char_u  *name;
  1712. {
  1713.     return (STRCMP(name, "builtin_gui") == 0 || STRCMP(name, "gui") == 0);
  1714. }
  1715. #endif
  1716. #if !defined(HAVE_TGETENT) || defined(AMIGA) || defined(PROTO)
  1717.     char_u *
  1718. tltoa(i)
  1719.     unsigned long i;
  1720. {
  1721.     static char_u buf[16];
  1722.     char_u *p;
  1723.     p = buf + 15;
  1724.     *p = '';
  1725.     do
  1726.     {
  1727. --p;
  1728. *p = (char_u) (i % 10 + '0');
  1729. i /= 10;
  1730.     }
  1731.     while (i > 0 && p > buf);
  1732.     return p;
  1733. }
  1734. #endif
  1735. #ifndef HAVE_TGETENT
  1736. /*
  1737.  * minimal tgoto() implementation.
  1738.  * no padding and we only parse for %i %d and %+char
  1739.  */
  1740. char *tgoto __ARGS((char *, int, int));
  1741.     char *
  1742. tgoto(cm, x, y)
  1743.     char *cm;
  1744.     int x, y;
  1745. {
  1746.     static char buf[30];
  1747.     char *p, *s, *e;
  1748.     if (!cm)
  1749. return "OOPS";
  1750.     e = buf + 29;
  1751.     for (s = buf; s < e && *cm; cm++)
  1752.     {
  1753. if (*cm != '%')
  1754. {
  1755.     *s++ = *cm;
  1756.     continue;
  1757. }
  1758. switch (*++cm)
  1759. {
  1760. case 'd':
  1761.     p = (char *)tltoa((unsigned long)y);
  1762.     y = x;
  1763.     while (*p)
  1764. *s++ = *p++;
  1765.     break;
  1766. case 'i':
  1767.     x++;
  1768.     y++;
  1769.     break;
  1770. case '+':
  1771.     *s++ = (char)(*++cm + y);
  1772.     y = x;
  1773.     break;
  1774. case '%':
  1775.     *s++ = *cm;
  1776.     break;
  1777. default:
  1778.     return "OOPS";
  1779. }
  1780.     }
  1781.     *s = '';
  1782.     return buf;
  1783. }
  1784. #endif /* HAVE_TGETENT */
  1785. /*
  1786.  * Set the terminal name and initialize the terminal options.
  1787.  * If "name" is NULL or empty, get the terminal name from the environment.
  1788.  * If that fails, use the default terminal name.
  1789.  */
  1790.     void
  1791. termcapinit(name)
  1792.     char_u *name;
  1793. {
  1794.     char_u *term;
  1795.     if (name != NULL && *name == NUL)
  1796. name = NULL;     /* empty name is equal to no name */
  1797.     term = name;
  1798. #ifdef __BEOS__
  1799.     /*
  1800.      * TERM environment variable is normally set to 'ansi' on the Bebox;
  1801.      * Since the BeBox doesn't quite support full ANSI yet, we use our
  1802.      * own custom 'ansi-beos' termcap instead, unless the -T option has
  1803.      * been given on the command line.
  1804.      */
  1805.     if (term == NULL
  1806.  && strcmp((char *)mch_getenv((char_u *)"TERM"), "ansi") == 0)
  1807. term = DEFAULT_TERM;
  1808. #endif
  1809. #ifndef WIN32
  1810.     if (term == NULL)
  1811. term = mch_getenv((char_u *)"TERM");
  1812. #endif
  1813.     if (term == NULL || *term == NUL)
  1814. term = DEFAULT_TERM;
  1815.     set_string_option_direct((char_u *)"term", -1, term, TRUE);
  1816.     /* Set the default terminal name. */
  1817.     set_string_default("term", term);
  1818.     set_string_default("ttytype", term);
  1819.     /*
  1820.      * Avoid using "term" here, because the next mch_getenv() may overwrite it.
  1821.      */
  1822.     set_termname(T_NAME != NULL ? T_NAME : term);
  1823. }
  1824. /*
  1825.  * the number of calls to ui_write is reduced by using the buffer "out_buf"
  1826.  */
  1827. #ifdef DOS16
  1828. # define OUT_SIZE 255 /* only have 640K total... */
  1829. #else
  1830. # define OUT_SIZE 2047
  1831. #endif
  1832.     /* Add one to allow mch_write() in os_win32.c to append a NUL */
  1833. static char_u out_buf[OUT_SIZE + 1];
  1834. static int out_pos = 0; /* number of chars in out_buf */
  1835. /*
  1836.  * out_flush(): flush the output buffer
  1837.  */
  1838.     void
  1839. out_flush()
  1840. {
  1841.     int     len;
  1842.     if (out_pos != 0)
  1843.     {
  1844. /* set out_pos to 0 before ui_write, to avoid recursiveness */
  1845. len = out_pos;
  1846. out_pos = 0;
  1847. ui_write(out_buf, len);
  1848.     }
  1849. }
  1850. #ifdef USE_GUI
  1851. /*
  1852.  * out_trash(): Throw away the contents of the output buffer
  1853.  */
  1854.     void
  1855. out_trash()
  1856. {
  1857.     out_pos = 0;
  1858. }
  1859. #endif
  1860. /*
  1861.  * out_char(c): put a character into the output buffer.
  1862.  * Flush it if it becomes full.
  1863.  * This should not be used for outputting text on the screen (use functions
  1864.  * like msg_puts() and screen_putchar() for that).
  1865.  */
  1866.     void
  1867. out_char(c)
  1868.     unsigned c;
  1869. {
  1870. #if defined(UNIX) || defined(VMS) || defined(AMIGA)
  1871.     if (c == 'n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
  1872. out_char('r');
  1873. #endif
  1874.     out_buf[out_pos++] = c;
  1875.     /* For testing we flush each time. */
  1876.     if (out_pos >= OUT_SIZE || p_wd)
  1877. out_flush();
  1878. }
  1879. static void out_char_nf __ARGS((unsigned));
  1880. /*
  1881.  * out_char_nf(c): like out_char(), but don't flush when p_wd is set
  1882.  */
  1883.     static void
  1884. out_char_nf(c)
  1885.     unsigned c;
  1886. {
  1887. #if defined(UNIX) || defined(VMS) || defined(AMIGA)
  1888.     if (c == 'n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
  1889. out_char_nf('r');
  1890. #endif
  1891.     out_buf[out_pos++] = c;
  1892.     if (out_pos >= OUT_SIZE)
  1893. out_flush();
  1894. }
  1895. /*
  1896.  * A never-padding out_str.
  1897.  * use this whenever you don't want to run the string through tputs.
  1898.  * tputs above is harmless, but tputs from the termcap library
  1899.  * is likely to strip off leading digits, that it mistakes for padding
  1900.  * information. (jw)
  1901.  * This should only be used for writing terminal codes, not for outputting
  1902.  * normal text (use functions like msg_puts() and screen_putchar() for that).
  1903.  */
  1904.     void
  1905. out_str_nf(s)
  1906.     char_u *s;
  1907. {
  1908.     if (out_pos > OUT_SIZE - 20)  /* avoid terminal strings being split up */
  1909. out_flush();
  1910.     while (*s)
  1911. out_char_nf(*s++);
  1912.     /* For testing we write one string at a time. */
  1913.     if (p_wd)
  1914. out_flush();
  1915. }
  1916. /*
  1917.  * out_str(s): Put a string character at a time into the output buffer.
  1918.  * If HAVE_TGETENT is defined use the termcap parser. (jw)
  1919.  * This should only be used for writing terminal codes, not for outputting
  1920.  * normal text (use functions like msg_puts() and screen_putchar() for that).
  1921.  */
  1922.     void
  1923. out_str(s)
  1924.     char_u  *s;
  1925. {
  1926.     if (out_pos > OUT_SIZE - 20)  /* avoid terminal strings being split up */
  1927. out_flush();
  1928.     if (s != NULL && *s)
  1929. #ifdef HAVE_TGETENT
  1930. tputs((char *)s, 1, TPUTSFUNCAST out_char_nf);
  1931. #else
  1932. while (*s)
  1933.     out_char_nf(*s++);
  1934. #endif
  1935.     /* For testing we write one string at a time. */
  1936.     if (p_wd)
  1937. out_flush();
  1938. }
  1939. /*
  1940.  * cursor positioning using termcap parser. (jw)
  1941.  */
  1942.     void
  1943. term_windgoto(row, col)
  1944.     int     row;
  1945.     int     col;
  1946. {
  1947.     OUT_STR(tgoto((char *)T_CM, col, row));
  1948. }
  1949.     void
  1950. term_cursor_right(i)
  1951.     int     i;
  1952. {
  1953.     OUT_STR(tgoto((char *)T_CRI, 0, i));
  1954. }
  1955.     void
  1956. term_append_lines(line_count)
  1957.     int     line_count;
  1958. {
  1959.     OUT_STR(tgoto((char *)T_CAL, 0, line_count));
  1960. }
  1961.     void
  1962. term_delete_lines(line_count)
  1963.     int     line_count;
  1964. {
  1965.     OUT_STR(tgoto((char *)T_CDL, 0, line_count));
  1966. }
  1967.     void
  1968. term_fg_color(n)
  1969.     int     n;
  1970. {
  1971.     /* Use "AF" termcap entry if present, "Sf" entry otherwise */
  1972.     if (*T_CAF)
  1973. term_color(T_CAF, n);
  1974.     else if (*T_CSF)
  1975. term_color(T_CSF, n);
  1976. }
  1977.     void
  1978. term_bg_color(n)
  1979.     int     n;
  1980. {
  1981.     /* Use "AB" termcap entry if present, "Sb" entry otherwise */
  1982.     if (*T_CAB)
  1983. term_color(T_CAB, n);
  1984.     else if (*T_CSB)
  1985. term_color(T_CSB, n);
  1986. }
  1987.     static void
  1988. term_color(s, n)
  1989.     char_u  *s;
  1990.     int     n;
  1991. {
  1992.     /* Special handling of 16 colors, because termcap can't handle it */
  1993.     if (n > 7 && atoi((char *)T_CCO) == 16
  1994.       && s[0] == ESC && s[1] == '[' && s[2] != NUL
  1995. #ifdef TERMINFO
  1996.       && STRCMP(s + 3, "%p1%dm") == 0
  1997. #else
  1998.       && STRCMP(s + 3, "%dm") == 0
  1999. #endif
  2000. )
  2001.     {
  2002. if (s[2] == '3') /* foreground */
  2003. {
  2004. #ifdef TERMINFO
  2005.     OUT_STR(tgoto("33[9%p1%dm", 0, n - 8));
  2006. #else
  2007.     OUT_STR(tgoto("33[9%dm", 0, n - 8));
  2008. #endif
  2009.     return;
  2010. }
  2011. if (s[2] == '4') /* background */
  2012. {
  2013. #ifdef TERMINFO
  2014.     OUT_STR(tgoto("33[10%p1%dm", 0, n - 8));
  2015. #else
  2016.     OUT_STR(tgoto("33[10%dm", 0, n - 8));
  2017. #endif
  2018.     return;
  2019. }
  2020.     }
  2021.     OUT_STR(tgoto((char *)s, 0, n));
  2022. }
  2023. /*
  2024.  * Make sure we have a valid set or terminal options.
  2025.  * Replace all entries that are NULL by empty_option
  2026.  */
  2027.     void
  2028. ttest(pairs)
  2029.     int pairs;
  2030. {
  2031.     char    *t = NULL;
  2032.     check_options();     /* make sure no options are NULL */
  2033.   /* hard requirements */
  2034.     if (*T_CL == NUL)     /* erase display */
  2035. t = "cl";
  2036.     if (*T_CM == NUL)     /* cursor motion */
  2037. t = "cm";
  2038.     if (t != NULL)
  2039. EMSG2("terminal capability %s required", t);
  2040. /*
  2041.  * if "cs" defined, use a scroll region, it's faster.
  2042.  */
  2043.     if (*T_CS != NUL)
  2044. scroll_region = TRUE;
  2045.     else
  2046. scroll_region = FALSE;
  2047.     if (pairs)
  2048.     {
  2049. /*
  2050.  * optional pairs
  2051.  */
  2052. /* TP goes to normal mode for TI (invert) and TB (bold) */
  2053. if (*T_ME == NUL)
  2054.     T_ME = T_MR = T_MD = T_MB = empty_option;
  2055. if (*T_SO == NUL || *T_SE == NUL)
  2056.     T_SO = T_SE = empty_option;
  2057. if (*T_US == NUL || *T_UE == NUL)
  2058.     T_US = T_UE = empty_option;
  2059. if (*T_CZH == NUL || *T_CZR == NUL)
  2060.     T_CZH = T_CZR = empty_option;
  2061. /* T_VE is needed even though T_VI is not defined */
  2062. if (*T_VE == NUL)
  2063.     T_VI = empty_option;
  2064. /* if 'mr' or 'me' is not defined use 'so' and 'se' */
  2065. if (*T_ME == NUL)
  2066. {
  2067.     T_ME = T_SE;
  2068.     T_MR = T_SO;
  2069.     T_MD = T_SO;
  2070. }
  2071. /* if 'so' or 'se' is not defined use 'mr' and 'me' */
  2072. if (*T_SO == NUL)
  2073. {
  2074.     T_SE = T_ME;
  2075.     if (*T_MR == NUL)
  2076. T_SO = T_MD;
  2077.     else
  2078. T_SO = T_MR;
  2079. }
  2080. /* if 'ZH' or 'ZR' is not defined use 'mr' and 'me' */
  2081. if (*T_CZH == NUL)
  2082. {
  2083.     T_CZR = T_ME;
  2084.     if (*T_MR == NUL)
  2085. T_CZH = T_MD;
  2086.     else
  2087. T_CZH = T_MR;
  2088. }
  2089. /* "Sb" and "Sf" come in pairs */
  2090. if (*T_CSB == NUL || *T_CSF == NUL)
  2091. {
  2092.     T_CSB = empty_option;
  2093.     T_CSF = empty_option;
  2094. }
  2095. /* "AB" and "AF" come in pairs */
  2096. if (*T_CAB == NUL || *T_CAF == NUL)
  2097. {
  2098.     T_CAB = empty_option;
  2099.     T_CAF = empty_option;
  2100. }
  2101. /* if 'Sb' and 'AB' are not defined, reset "Co" */
  2102. if (*T_CSB == NUL && *T_CAB == NUL)
  2103.     T_CCO = empty_option;
  2104. /* Set 'weirdinvert' according to value of 't_xs' */
  2105. p_wiv = (*T_XS != NUL);
  2106.     }
  2107.     need_gather = TRUE;
  2108. }
  2109. /*
  2110.  * Represent the given long_u as individual bytes, with the most significant
  2111.  * byte first, and store them in dst.
  2112.  */
  2113.     void
  2114. add_long_to_buf(val, dst)
  2115.     long_u  val;
  2116.     char_u  *dst;
  2117. {
  2118.     int     i;
  2119.     int     shift;
  2120.     for (i = 1; i <= sizeof(long_u); i++)
  2121.     {
  2122. shift = 8 * (sizeof(long_u) - i);
  2123. dst[i - 1] = (char_u) ((val >> shift) & 0xff);
  2124.     }
  2125. }
  2126. /*
  2127.  * Interpret the next string of bytes in buf as a long integer, with the most
  2128.  * significant byte first.  Note that it is assumed that buf has been through
  2129.  * inchar(), so that NUL and K_SPECIAL will be represented as three bytes each.
  2130.  * Puts result in val, and returns the number of bytes read from buf
  2131.  * (between sizeof(long_u) and 2 * sizeof(long_u)), or -1 if not enough bytes
  2132.  * were present.
  2133.  */
  2134.     int
  2135. get_long_from_buf(buf, val)
  2136.     char_u  *buf;
  2137.     long_u  *val;
  2138. {
  2139.     int     len;
  2140.     char_u  bytes[sizeof(long_u)];
  2141.     int     i;
  2142.     int     shift;
  2143.     *val = 0;
  2144.     len = get_bytes_from_buf(buf, bytes, (int)sizeof(long_u));
  2145.     if (len != -1)
  2146.     {
  2147. for (i = 0; i < sizeof(long_u); i++)
  2148. {
  2149.     shift = 8 * (sizeof(long_u) - 1 - i);
  2150.     *val += (long_u)bytes[i] << shift;
  2151. }
  2152.     }
  2153.     return len;
  2154. }
  2155. /*
  2156.  * Read the next num_bytes bytes from buf, and store them in bytes.  Assume
  2157.  * that buf has been through inchar(). Returns the actual number of bytes used
  2158.  * from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
  2159.  * available.
  2160.  */
  2161.     static int
  2162. get_bytes_from_buf(buf, bytes, num_bytes)
  2163.     char_u  *buf;
  2164.     char_u  *bytes;
  2165.     int     num_bytes;
  2166. {
  2167.     int     len = 0;
  2168.     int     i;
  2169.     char_u  c;
  2170.     for (i = 0; i < num_bytes; i++)
  2171.     {
  2172. if ((c = buf[len++]) == NUL)
  2173.     return -1;
  2174. if (c == K_SPECIAL)
  2175. {
  2176.     if (buf[len] == NUL || buf[len + 1] == NUL)     /* cannot happen? */
  2177. return -1;
  2178.     if (buf[len++] == (int)KS_ZERO)
  2179. c = NUL;
  2180.     ++len; /* skip K_FILLER */
  2181.     /* else it should be KS_SPECIAL, and c already equals K_SPECIAL */
  2182. }
  2183. bytes[i] = c;
  2184.     }
  2185.     return len;
  2186. }
  2187.     void
  2188. check_winsize()
  2189. {
  2190.     static int old_Rows = 0;
  2191.     if (Columns < MIN_COLUMNS)
  2192. Columns = MIN_COLUMNS;
  2193.     if (Rows < min_rows()) /* need room for one window and command line */
  2194. Rows = min_rows();
  2195.     if (old_Rows != Rows)
  2196.     {
  2197. old_Rows = Rows;
  2198. screen_new_rows(); /* may need to update window sizes */
  2199.     }
  2200. }
  2201. /*
  2202.  * set window size
  2203.  * If 'mustset' is TRUE, we must set Rows and Columns, do not get real
  2204.  * window size (this is used for the :win command).
  2205.  * If 'mustset' is FALSE, we may try to get the real window size and if
  2206.  * it fails use 'width' and 'height'.
  2207.  */
  2208.     void
  2209. set_winsize(width, height, mustset)
  2210.     int     width, height;
  2211.     int     mustset;
  2212. {
  2213.     static int busy = FALSE;
  2214.     /*
  2215.      * Avoid recursiveness, can happen when setting the window size causes
  2216.      * another window-changed signal.
  2217.      */
  2218.     if (busy)
  2219. return;
  2220.     if (width < 0 || height < 0)    /* just checking... */
  2221. return;
  2222.     if (State == HITRETURN || State == SETWSIZE) /* postpone the resizing */
  2223.     {
  2224. State = SETWSIZE;
  2225. return;
  2226.     }
  2227.     ++busy;
  2228.     if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
  2229. screenclear();
  2230.     else
  2231. screen_start();     /* don't know where cursor is now */
  2232. #ifdef AMIGA
  2233.     out_flush();     /* must do this before mch_get_winsize() for some
  2234.        obscure reason */
  2235. #endif /* AMIGA */
  2236.     if (mustset || (ui_get_winsize() == FAIL && height != 0))
  2237.     {
  2238. Rows = height;
  2239. Columns = width;
  2240. check_winsize(); /* always check, to get p_scroll right */
  2241. ui_set_winsize();
  2242.     }
  2243.     else
  2244. check_winsize(); /* always check, to get p_scroll right */
  2245.     if (!starting)
  2246.     {
  2247. maketitle();
  2248. /*
  2249.  * We only redraw when it's needed:
  2250.  * - While at the more prompt or executing an external command, don't
  2251.  *   redraw, but position the cursor.
  2252.  * - While editing the command line, only redraw that.
  2253.  * - in Ex mode, don't redraw anything.
  2254.  * - Otherwise, redraw right now, and position the cursor.
  2255.  * Always need to call update_screen() or screenalloc(), to make
  2256.  * sure Rows/Columns and the size of NextScreen is correct!
  2257.  */
  2258. if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM)
  2259. {
  2260.     screenalloc(FALSE);
  2261.     if (State == ASKMORE)
  2262.     {
  2263. msg_moremsg(FALSE); /* display --more-- message again */
  2264. msg_row = Rows - 1;
  2265.     }
  2266. #ifdef CON_DIALOG
  2267.     else if (State == CONFIRM)
  2268.     {
  2269. display_confirm_msg(); /* display ":confirm" message again */
  2270. msg_row = Rows - 1;
  2271.     }
  2272. #endif
  2273.     else
  2274. windgoto(msg_row, msg_col); /* put cursor back */
  2275. }
  2276. else if (State == CMDLINE)
  2277. {
  2278.     update_screen(NOT_VALID);
  2279.     redrawcmdline();
  2280. }
  2281. else if (exmode_active)
  2282. {
  2283.     screenalloc(FALSE);
  2284. }
  2285. else
  2286. {
  2287.     update_topline();
  2288.     update_screen(NOT_VALID);
  2289.     if (redrawing())
  2290. setcursor();
  2291. }
  2292. cursor_on();     /* redrawing may have switched it off */
  2293.     }
  2294.     out_flush();
  2295.     --busy;
  2296. }
  2297. /*
  2298.  * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
  2299.  * commands and Ex mode).
  2300.  */
  2301.     void
  2302. settmode(tmode)
  2303.     int  tmode;
  2304. {
  2305.     static int oldtmode = TMODE_COOK;
  2306. #ifdef USE_GUI
  2307.     /* don't set the term where gvim was started to any mode */
  2308.     if (gui.in_use)
  2309. return;
  2310. #endif
  2311.     if (full_screen)
  2312.     {
  2313. /* In Ex mode, never set to RAW */
  2314. if (exmode_active)
  2315.     tmode = TMODE_COOK;
  2316. /*
  2317.  * When returning after calling a shell we want to really set the
  2318.  * terminal to raw mode, even though we think it already is, because
  2319.  * the shell program may have reset the terminal mode.
  2320.  * When we think the terminal is normal, don't try to set it to
  2321.  * normal again, because that causes problems (logout!) on some
  2322.  * machines.
  2323.  */
  2324. if (tmode != TMODE_COOK || oldtmode != TMODE_COOK)
  2325. {
  2326.     out_flush();
  2327.     mch_settmode(tmode);    /* machine specific function */
  2328. #ifdef USE_MOUSE
  2329.     if (tmode != TMODE_RAW)
  2330. mch_setmouse(FALSE); /* switch mouse off */
  2331.     else
  2332. setmouse(); /* may switch mouse on */
  2333. #endif
  2334.     out_flush();
  2335.     oldtmode = tmode;
  2336. }
  2337.     }
  2338. }
  2339.     void
  2340. starttermcap()
  2341. {
  2342.     screen_stop_highlight();
  2343.     if (full_screen && !termcap_active)
  2344.     {
  2345. out_str(T_TI); /* start termcap mode */
  2346. out_str(T_KS); /* start "keypad transmit" mode */
  2347. out_flush();
  2348. termcap_active = TRUE;
  2349. screen_start(); /* don't know where cursor is now */
  2350.     }
  2351. }
  2352.     void
  2353. stoptermcap()
  2354. {
  2355.     screen_stop_highlight();
  2356.     reset_cterm_colors();
  2357.     if (termcap_active)
  2358.     {
  2359. out_str(T_KE); /* stop "keypad transmit" mode */
  2360. out_flush();
  2361. termcap_active = FALSE;
  2362. cursor_on(); /* just in case it is still off */
  2363. out_str(T_TE); /* stop termcap mode */
  2364. screen_start(); /* don't know where cursor is now */
  2365. out_flush();
  2366.     }
  2367. }
  2368. /*
  2369.  * Return TRUE when saving and restoring the screen.
  2370.  */
  2371.     int
  2372. swapping_screen()
  2373. {
  2374.     return (*T_TI != NUL);
  2375. }
  2376. #ifdef USE_MOUSE
  2377. /*
  2378.  * setmouse() - switch mouse on/off depending on current mode and 'mouse'
  2379.  */
  2380.     void
  2381. setmouse()
  2382. {
  2383.     int     checkfor;
  2384. # ifdef USE_GUI
  2385.     if (gui.in_use)
  2386. return;
  2387. # endif
  2388.     if (*p_mouse == NUL)     /* be quick when mouse is off */
  2389. return;
  2390.     if (VIsual_active)
  2391. checkfor = MOUSE_VISUAL;
  2392.     else if (State == HITRETURN)
  2393. checkfor = MOUSE_RETURN;
  2394.     else if (State & INSERT)
  2395. checkfor = MOUSE_INSERT;
  2396.     else if (State & CMDLINE)
  2397. checkfor = MOUSE_COMMAND;
  2398.     else if (State == CONFIRM)     /* don't use mouse for ":confirm" */
  2399. checkfor = ' ';
  2400.     else
  2401. checkfor = MOUSE_NORMAL;    /* assume normal mode */
  2402.     if (mouse_has(checkfor))
  2403. mch_setmouse(TRUE);
  2404.     else
  2405. mch_setmouse(FALSE);
  2406. }
  2407. /*
  2408.  * Return TRUE if
  2409.  * - "c" is in 'mouse', or
  2410.  * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
  2411.  * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
  2412.  *   normal editing mode (not at hit-return message).
  2413.  */
  2414.     int
  2415. mouse_has(c)
  2416.     int     c;
  2417. {
  2418.     char_u *p;
  2419.     for (p = p_mouse; *p; ++p)
  2420. switch (*p)
  2421. {
  2422.     case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
  2423.   return TRUE;
  2424.       break;
  2425.     case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
  2426.  return TRUE;
  2427.      break;
  2428.     default: if (c == *p) return TRUE; break;
  2429. }
  2430.     return FALSE;
  2431. }
  2432. /*
  2433.  * Return TRUE when 'mousemodel' is set to "popup".
  2434.  */
  2435.     int
  2436. mouse_model_popup()
  2437. {
  2438.     return (p_mousem[0] == 'p');
  2439. }
  2440. #endif
  2441. /*
  2442.  * By outputting the 'cursor very visible' termcap code, for some windowed
  2443.  * terminals this makes the screen scrolled to the correct position.
  2444.  * Used when starting Vim or returning from a shell.
  2445.  */
  2446.     void
  2447. scroll_start()
  2448. {
  2449.     if (*T_VS != NUL)
  2450.     {
  2451. out_str(T_VS);
  2452. out_str(T_VE);
  2453. screen_start(); /* don't know where cursor is now */
  2454.     }
  2455. }
  2456. /*
  2457.  * enable cursor, unless in Visual mode.
  2458.  */
  2459. static int cursor_is_off = FALSE;
  2460.     void
  2461. cursor_on()
  2462. {
  2463.     if (cursor_is_off)
  2464.     {
  2465. out_str(T_VE);
  2466. cursor_is_off = FALSE;
  2467.     }
  2468. }
  2469.     void
  2470. cursor_off()
  2471. {
  2472.     if (full_screen)
  2473.     {
  2474. if (!cursor_is_off)
  2475.     out_str(T_VI);     /* disable cursor */
  2476. cursor_is_off = TRUE;
  2477.     }
  2478. }
  2479. /*
  2480.  * Set scrolling region for window 'wp'.
  2481.  * The region starts 'off' lines from the start of the window.
  2482.  */
  2483.     void
  2484. scroll_region_set(wp, off)
  2485.     WIN     *wp;
  2486.     int     off;
  2487. {
  2488.     OUT_STR(tgoto((char *)T_CS, wp->w_winpos + wp->w_height - 1,
  2489.  wp->w_winpos + off));
  2490.     screen_start();     /* don't know where cursor is now */
  2491. }
  2492. /*
  2493.  * Reset scrolling region to the whole screen.
  2494.  */
  2495.     void
  2496. scroll_region_reset()
  2497. {
  2498.     OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0));
  2499.     screen_start();     /* don't know where cursor is now */
  2500. }
  2501. /*
  2502.  * List of terminal codes that are currently recognized.
  2503.  */
  2504. struct termcode
  2505. {
  2506.     char_u  name[2];     /* termcap name of entry */
  2507.     char_u  *code;     /* terminal code (in allocated memory) */
  2508.     int     len;     /* STRLEN(code) */
  2509. } *termcodes = NULL;
  2510. static int  tc_max_len = 0; /* number of entries that termcodes[] can hold */
  2511. static int  tc_len = 0;     /* current number of entries in termcodes[] */
  2512.     void
  2513. clear_termcodes()
  2514. {
  2515.     while (tc_len > 0)
  2516. vim_free(termcodes[--tc_len].code);
  2517.     vim_free(termcodes);
  2518.     termcodes = NULL;
  2519.     tc_max_len = 0;
  2520. #ifdef HAVE_TGETENT
  2521.     BC = (char *)empty_option;
  2522.     UP = (char *)empty_option;
  2523.     PC = NUL; /* set pad character to NUL */
  2524.     ospeed = 0;
  2525. #endif
  2526.     need_gather = TRUE; /* need to fill termleader[] */
  2527. }
  2528. /*
  2529.  * Add a new entry to the list of terminal codes.
  2530.  * The list is kept alphabetical for ":set termcap"
  2531.  */
  2532.     void
  2533. add_termcode(name, string)
  2534.     char_u  *name;
  2535.     char_u  *string;
  2536. {
  2537.     struct termcode *new_tc;
  2538.     int     i, j;
  2539.     char_u     *s;
  2540.     if (string == NULL || *string == NUL)
  2541.     {
  2542. del_termcode(name);
  2543. return;
  2544.     }
  2545.     s = vim_strsave(string);
  2546.     if (s == NULL)
  2547. return;
  2548.     need_gather = TRUE; /* need to fill termleader[] */
  2549.     /*
  2550.      * need to make space for more entries
  2551.      */
  2552.     if (tc_len == tc_max_len)
  2553.     {
  2554. tc_max_len += 20;
  2555. new_tc = (struct termcode *)alloc(
  2556.     (unsigned)(tc_max_len * sizeof(struct termcode)));
  2557. if (new_tc == NULL)
  2558. {
  2559.     tc_max_len -= 20;
  2560.     return;
  2561. }
  2562. for (i = 0; i < tc_len; ++i)
  2563.     new_tc[i] = termcodes[i];
  2564. vim_free(termcodes);
  2565. termcodes = new_tc;
  2566.     }
  2567.     /*
  2568.      * Look for existing entry with the same name, it is replaced.
  2569.      * Look for an existing entry that is alphabetical higher, the new entry
  2570.      * is inserted in front of it.
  2571.      */
  2572.     for (i = 0; i < tc_len; ++i)
  2573.     {
  2574. if (termcodes[i].name[0] < name[0])
  2575.     continue;
  2576. if (termcodes[i].name[0] == name[0])
  2577. {
  2578.     if (termcodes[i].name[1] < name[1])
  2579. continue;
  2580.     /*
  2581.      * Exact match: Replace old code.
  2582.      */
  2583.     if (termcodes[i].name[1] == name[1])
  2584.     {
  2585. vim_free(termcodes[i].code);
  2586. --tc_len;
  2587. break;
  2588.     }
  2589. }
  2590. /*
  2591.  * Found alphabetical larger entry, move rest to insert new entry
  2592.  */
  2593. for (j = tc_len; j > i; --j)
  2594.     termcodes[j] = termcodes[j - 1];
  2595. break;
  2596.     }
  2597.     termcodes[i].name[0] = name[0];
  2598.     termcodes[i].name[1] = name[1];
  2599.     termcodes[i].code = s;
  2600.     termcodes[i].len = STRLEN(s);
  2601.     ++tc_len;
  2602. }
  2603.     char_u  *
  2604. find_termcode(name)
  2605.     char_u  *name;
  2606. {
  2607.     int     i;
  2608.     for (i = 0; i < tc_len; ++i)
  2609. if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
  2610.     return termcodes[i].code;
  2611.     return NULL;
  2612. }
  2613.     char_u *
  2614. get_termcode(i)
  2615.     int     i;
  2616. {
  2617.     if (i >= tc_len)
  2618. return NULL;
  2619.     return &termcodes[i].name[0];
  2620. }
  2621.     void
  2622. del_termcode(name)
  2623.     char_u  *name;
  2624. {
  2625.     int     i;
  2626.     if (termcodes == NULL) /* nothing there yet */
  2627. return;
  2628.     need_gather = TRUE; /* need to fill termleader[] */
  2629.     for (i = 0; i < tc_len; ++i)
  2630. if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
  2631. {
  2632.     vim_free(termcodes[i].code);
  2633.     --tc_len;
  2634.     while (i < tc_len)
  2635.     {
  2636. termcodes[i] = termcodes[i + 1];
  2637. ++i;
  2638.     }
  2639.     return;
  2640. }
  2641.     /* not found. Give error message? */
  2642. }
  2643. /*
  2644.  * Check if typebuf[] contains a terminal key code.
  2645.  * Check from typebuf[typeoff] to typebuf[typeoff + max_offset].
  2646.  * Return 0 for no match, -1 for partial match, > 0 for full match.
  2647.  * With a match, the match is removed, the replacement code is inserted in
  2648.  * typebuf[] and the number of characters in typebuf[] is returned.
  2649.  */
  2650.     int
  2651. check_termcode(max_offset)
  2652.     int     max_offset;
  2653. {
  2654.     char_u *tp;
  2655.     char_u *p;
  2656.     int slen = 0; /* init for GCC */
  2657.     int len;
  2658.     int offset;
  2659.     char_u key_name[2];
  2660.     int new_slen;
  2661.     int extra;
  2662.     char_u string[MAX_KEY_CODE_LEN + 1];
  2663.     int i, j;
  2664. #ifdef USE_GUI
  2665.     long_u val;
  2666. #endif
  2667. #ifdef USE_MOUSE
  2668. # if !defined(UNIX) || defined(XTERM_MOUSE) || defined(USE_GUI)
  2669.     char_u bytes[3];
  2670.     int num_bytes;
  2671. # endif
  2672.     int mouse_code = 0;     /* init for GCC */
  2673.     int modifiers;
  2674.     int is_click, is_drag;
  2675.     int current_button;
  2676.     static int held_button = MOUSE_RELEASE;
  2677.     static int orig_num_clicks = 1;
  2678.     static int orig_mouse_code = 0x0;
  2679. # if defined(UNIX) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
  2680.     static int orig_mouse_col = 0;
  2681.     static int orig_mouse_row = 0;
  2682.     static linenr_t orig_topline = 0;
  2683.     static struct timeval  orig_mouse_time = {0, 0};
  2684. /* time of previous mouse click */
  2685.     struct timeval  mouse_time; /* time of current mouse click */
  2686.     long timediff; /* elapsed time in msec */
  2687. # endif
  2688. #endif
  2689.     /*
  2690.      * Speed up the checks for terminal codes by gathering all first bytes
  2691.      * used in termleader[].  Often this is just a single <Esc>.
  2692.      */
  2693.     if (need_gather)
  2694. gather_termleader();
  2695.     /*
  2696.      * Check at several positions in typebuf[], to catch something like
  2697.      * "x<Up>" that can be mapped. Stop at max_offset, because characters
  2698.      * after that cannot be used for mapping, and with @r commands typebuf[]
  2699.      * can become very long.
  2700.      * This is used often, KEEP IT FAST!
  2701.      */
  2702.     for (offset = 0; offset < typelen && offset < max_offset; ++offset)
  2703.     {
  2704. tp = typebuf + typeoff + offset;
  2705. /*
  2706.  * Don't check characters after K_SPECIAL, those are already
  2707.  * translated terminal chars (avoid translating ~@^Hx).
  2708.  */
  2709. if (*tp == K_SPECIAL)
  2710. {
  2711.     offset += 2; /* there are always 2 extra characters */
  2712.     continue;
  2713. }
  2714. /*
  2715.  * Skip this position if the character does not appear as the first
  2716.  * character in term_strings. This speeds up a lot, since most
  2717.  * termcodes start with the same character (ESC or CSI).
  2718.  */
  2719. i = *tp;
  2720. for (p = termleader; *p && *p != i; ++p)
  2721.     ;
  2722. if (*p == NUL)
  2723.     continue;
  2724. /*
  2725.  * Skip this position if p_ek is not set and
  2726.  * typebuf[typeoff + offset] is an ESC and we are in insert mode
  2727.  */
  2728. if (*tp == ESC && !p_ek && (State & INSERT))
  2729.     continue;
  2730. len = typelen - offset; /* length of the input */
  2731. new_slen = 0; /* Length of what will replace the termcode */
  2732. key_name[0] = NUL; /* no key name found yet */
  2733. #ifdef USE_GUI
  2734. if (gui.in_use)
  2735. {
  2736.     /*
  2737.      * GUI special key codes are all of the form [CSI xx].
  2738.      */
  2739.     if (*tp == CSI)     /* Special key from GUI */
  2740.     {
  2741. if (len < 3)
  2742.     return -1;     /* Shouldn't happen */
  2743. slen = 3;
  2744. key_name[0] = tp[1];
  2745. key_name[1] = tp[2];
  2746.     }
  2747. }
  2748. else
  2749. #endif /* USE_GUI */
  2750. {
  2751.     for (i = 0; i < tc_len; ++i)
  2752.     {
  2753. /*
  2754.  * Ignore the entry if we are not at the start of typebuf[]
  2755.  * and there are not enough characters to make a match.
  2756.  */
  2757. slen = termcodes[i].len;
  2758. if (offset && len < slen)
  2759.     continue;
  2760. if (STRNCMP(termcodes[i].code, tp,
  2761.      (size_t)(slen > len ? len : slen)) == 0)
  2762. {
  2763.     if (len < slen) /* got a partial sequence */
  2764. return -1; /* need to get more chars */
  2765.     /*
  2766.      * When found a keypad key, check if there is another key
  2767.      * that matches and use that one.  This makes <Home> to be
  2768.      * found instead of <kHome> when they produce the same
  2769.      * key code.
  2770.      */
  2771.     if (termcodes[i].name[0] == 'K' &&
  2772. isdigit(termcodes[i].name[1]))
  2773.     {
  2774. for (j = i + 1; j < tc_len; ++j)
  2775.     if (termcodes[j].len == slen &&
  2776.     STRNCMP(termcodes[i].code,
  2777.     termcodes[j].code, slen) == 0)
  2778.     {
  2779. i = j;
  2780. break;
  2781.     }
  2782.     }
  2783.     /* replace K_XF1 by K_F1, K_XF1 by K_F2, etc. */
  2784.     if (termcodes[i].name[0] == KS_EXTRA)
  2785. switch (termcodes[i].name[1])
  2786. {
  2787.     case KE_XF1: termcodes[i].name[0] = 'k';
  2788.  termcodes[i].name[1] = '1';
  2789.  break;
  2790.     case KE_XF2: termcodes[i].name[0] = 'k';
  2791.  termcodes[i].name[1] = '2';
  2792.  break;
  2793.     case KE_XF3: termcodes[i].name[0] = 'k';
  2794.  termcodes[i].name[1] = '3';
  2795.  break;
  2796.     case KE_XF4: termcodes[i].name[0] = 'k';
  2797.  termcodes[i].name[1] = '4';
  2798.  break;
  2799. }
  2800.     key_name[0] = termcodes[i].name[0];
  2801.     key_name[1] = termcodes[i].name[1];
  2802.     break;
  2803. }
  2804.     }
  2805. }
  2806. if (key_name[0] == NUL)
  2807.     continue;     /* No match at this position, try next one */
  2808. /* We only get here when we have a complete termcode match */
  2809. #ifdef USE_MOUSE
  2810. /*
  2811.  * If it is a mouse click, get the coordinates.
  2812.  */
  2813. if (key_name[0] == (int)KS_MOUSE
  2814. # ifdef NETTERM_MOUSE
  2815. || key_name[0] == (int)KS_NETTERM_MOUSE
  2816. # endif
  2817. # ifdef DEC_MOUSE
  2818. || key_name[0] == (int)KS_DEC_MOUSE
  2819. # endif
  2820. )
  2821. {
  2822.     is_click = is_drag = FALSE;
  2823. #if !defined(UNIX) || defined(XTERM_MOUSE)
  2824.     if (key_name[0] == (int)KS_MOUSE)
  2825.     {
  2826. /*
  2827.  * For xterm and MSDOS we get "<t_mouse>scr", where
  2828.  *  s == encoded button state (0x20 = left, 0x22 = right, etc.)
  2829.  *  c == column + ' ' + 1 == column + 33
  2830.  *  r == row + ' ' + 1 == row + 33
  2831.  *
  2832.  * The coordinates are passed on through global variables. Ugly,
  2833.  * but this avoids trouble with mouse clicks at an unexpected
  2834.  * moment and allows for mapping them.
  2835.  */
  2836. num_bytes = get_bytes_from_buf(tp + slen, bytes, 3);
  2837. if (num_bytes == -1) /* not enough coordinates */
  2838.     return -1;
  2839. mouse_code = bytes[0];
  2840. mouse_col = bytes[1] - ' ' - 1;
  2841. mouse_row = bytes[2] - ' ' - 1;
  2842. slen += num_bytes;
  2843.     }
  2844. #endif /* !UNIX || XTERM_MOUSE */
  2845. #ifdef NETTERM_MOUSE
  2846.     if (key_name[0] == (int)KS_NETTERM_MOUSE)
  2847.     {
  2848. int mc, mr;
  2849. /* expect a rather limited sequence like: balancing {
  2850.  * 33}6,45r
  2851.  * '6' is the row, 45 is the column
  2852.  */
  2853. p = tp + slen;
  2854. mr = getdigits(&p);
  2855. if (*p++ != ',')
  2856.     return -1;
  2857. mc = getdigits(&p);
  2858. if (*p++ != 'r')
  2859.     return -1;
  2860. mouse_col = mc - 1;
  2861. mouse_row = mr - 1;
  2862. mouse_code = MOUSE_LEFT;
  2863. slen += (p - (tp + slen));
  2864.     }
  2865. #endif /* NETTERM_MOUSE */
  2866. #ifdef DEC_MOUSE
  2867.     if (key_name[0] == (int)KS_DEC_MOUSE)
  2868.     {
  2869.        /* The DEC Locator Input Model
  2870. * Netterm delivers the code sequence:
  2871. *  33[2;4;24;80&w  (left button down)
  2872. *  33[3;0;24;80&w  (left button up)
  2873. *  33[6;1;24;80&w  (right button down)
  2874. *  33[7;0;24;80&w  (right button up)
  2875. * CSI Pe ; Pb ; Pr ; Pc ; Pp & w
  2876. * Pe is the event code
  2877. * Pb is the button code
  2878. * Pr is the row coordinate
  2879. * Pc is the column coordinate
  2880. * Pp is the third coordinate (page number)
  2881. * Pe, the event code indicates what event caused this report
  2882. *    The following event codes are defined:
  2883. *    0 - request, the terminal received an explicit request
  2884. *  for a locator report, but the locator is unavailable
  2885. *    1 - request, the terminal received an explicit request
  2886. *  for a locator report
  2887. *    2 - left button down
  2888. *    3 - left button up
  2889. *    4 - middle button down
  2890. *    5 - middle button up
  2891. *    6 - right button down
  2892. *    7 - right button up
  2893. *    8 - fourth button down
  2894. *    9 - fourth button up
  2895. *    10 - locator outside filter rectangle
  2896. * Pb, the button code, ASCII decimal 0-15 indicating which
  2897. *   buttons are down if any. The state of the four buttons
  2898. *   on the locator correspond to the low four bits of the
  2899. *   decimal value,
  2900. *   "1" means button depressed
  2901. *   0 - no buttons down,
  2902. *   1 - right,
  2903. *   2 - middle,
  2904. *   4 - left,
  2905. *   8 - fourth
  2906. * Pr is the row coordinate of the locator position in the page,
  2907. *   encoded as an ASCII decimal value.
  2908. *   If Pr is omitted, the locator position is undefined
  2909. *   (outside the terminal window for example).
  2910. * Pc is the column coordinate of the locator position in the
  2911. *   page, encoded as an ASCII decimal value.
  2912. *   If Pc is omitted, the locator position is undefined
  2913. *   (outside the terminal window for example).
  2914. * Pp is the page coordinate of the locator position
  2915. *   encoded as an ASCII decimal value.
  2916. *   The page coordinate may be omitted if the locator is on
  2917. *   page one (the default).
  2918. */
  2919. int Pe, Pb, Pr, Pc /* , Pp */;
  2920. p = tp + slen;
  2921. /* get event status */
  2922. Pe = getdigits(&p);
  2923. if (*p++ != ';')
  2924.     return -1;
  2925. /* get button status */
  2926. Pb = getdigits(&p);
  2927. if (*p++ != ';')
  2928.     return -1;
  2929. /* get row status */
  2930. Pr = getdigits(&p);
  2931. if (*p++ != ';')
  2932.     return -1;
  2933. /* get column status */
  2934. Pc = getdigits(&p);
  2935. /* the page parameter is optional */
  2936. if (*p == ';')
  2937. {
  2938.     p++;
  2939.     /* Pp = getdigits(&p); */
  2940. }
  2941. /* else
  2942.     Pp = 0; */
  2943. if (*p++ != '&')
  2944.     return -1;
  2945. if (*p++ != 'w')
  2946.     return -1;
  2947. mouse_code = 0;
  2948. switch (Pe)
  2949. {
  2950. case  0: return -1; /* position request while unavailable */
  2951. case  1: /* a response to a locator position request includes
  2952.     the status of all buttons */
  2953.  Pb &= 7;   /* mask off and ignore fourth button */
  2954.  if (Pb & 4)
  2955.      mouse_code  = MOUSE_LEFT;
  2956.  if (Pb & 2)
  2957.      mouse_code  = MOUSE_MIDDLE;
  2958.  if (Pb & 1)
  2959.      mouse_code  = MOUSE_RIGHT;
  2960.  if (Pb)
  2961.  {
  2962.      held_button = mouse_code;
  2963.      mouse_code |= MOUSE_DRAG;
  2964.      WantQueryMouse = 1;
  2965.  }
  2966.  is_drag = TRUE;
  2967.  showmode();
  2968.  break;
  2969. case  2: mouse_code = MOUSE_LEFT;
  2970.  WantQueryMouse = 1;
  2971.  break;
  2972. case  3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
  2973.  break;
  2974. case  4: mouse_code = MOUSE_MIDDLE;
  2975.  WantQueryMouse = 1;
  2976.  break;
  2977. case  5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
  2978.  break;
  2979. case  6: mouse_code = MOUSE_RIGHT;
  2980.  WantQueryMouse = 1;
  2981.  break;
  2982. case  7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
  2983.  break;
  2984. case  8: return -1; /* fourth button down */
  2985. case  9: return -1; /* fourth button up */
  2986. case 10: return -1; /* mouse outside of filter rectangle */
  2987. default: return -1; /* should never occur */
  2988. }
  2989. /* we ignore the Pp word */
  2990. mouse_col = Pc - 1;
  2991. mouse_row = Pr - 1;
  2992. slen += (p - (tp + slen));
  2993.     }
  2994. #endif /* DEC_MOUSE */
  2995.     /* Interpret the mouse code */
  2996.     current_button = (mouse_code & MOUSE_CLICK_MASK);
  2997.     if (current_button == MOUSE_RELEASE)
  2998.     {
  2999. /*
  3000.  * If we get a mouse drag or release event when
  3001.  * there is no mouse button held down (held_button ==
  3002.  * MOUSE_RELEASE), produce a K_IGNORE below.
  3003.  * (can happen when you hold down two buttons
  3004.  * and then let them go, or click in the menu bar, but not
  3005.  * on a menu, and drag into the text).
  3006.  */
  3007. if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
  3008.     is_drag = TRUE;
  3009. current_button = held_button;
  3010.     }
  3011.     else
  3012.     {
  3013. #if defined(UNIX) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
  3014. # ifdef USE_GUI
  3015. /*
  3016.  * Only for Unix, when GUI is not active, we handle
  3017.  * multi-clicks here.
  3018.  */
  3019. if (!gui.in_use)
  3020. # endif
  3021. {
  3022.     /*
  3023.      * Compute the time elapsed since the previous mouse click.
  3024.      */
  3025.     gettimeofday(&mouse_time, NULL);
  3026.     timediff = (mouse_time.tv_usec -
  3027.       orig_mouse_time.tv_usec) / 1000;
  3028.     if (timediff < 0)
  3029. --orig_mouse_time.tv_sec;
  3030.     timediff += (mouse_time.tv_sec -
  3031.        orig_mouse_time.tv_sec) * 1000;
  3032.     orig_mouse_time = mouse_time;
  3033.     if (mouse_code == orig_mouse_code &&
  3034.     timediff < p_mouset &&
  3035.     orig_num_clicks != 4 &&
  3036.     orig_mouse_col == mouse_col &&
  3037.     orig_mouse_row == mouse_row &&
  3038.     orig_topline == curwin->w_topline)
  3039. ++orig_num_clicks;
  3040.     else
  3041. orig_num_clicks = 1;
  3042.     orig_mouse_col = mouse_col;
  3043.     orig_mouse_row = mouse_row;
  3044.     orig_topline = curwin->w_topline;
  3045. }
  3046. # ifdef USE_GUI
  3047. else
  3048.     orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
  3049. # endif
  3050. #else
  3051. orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
  3052. #endif
  3053. is_click = TRUE;
  3054. orig_mouse_code = mouse_code;
  3055.     }
  3056.     if (!is_drag)
  3057. held_button = mouse_code & MOUSE_CLICK_MASK;
  3058.     /*
  3059.      * Translate the actual mouse event into a pseudo mouse event.
  3060.      * First work out what modifiers are to be used.
  3061.      */
  3062.     modifiers = 0x0;
  3063.     if (orig_mouse_code & MOUSE_SHIFT)
  3064. modifiers |= MOD_MASK_SHIFT;
  3065.     if (orig_mouse_code & MOUSE_CTRL)
  3066. modifiers |= MOD_MASK_CTRL;
  3067.     if (orig_mouse_code & MOUSE_ALT)
  3068. modifiers |= MOD_MASK_ALT;
  3069.     if (orig_num_clicks == 2)
  3070. modifiers |= MOD_MASK_2CLICK;
  3071.     else if (orig_num_clicks == 3)
  3072. modifiers |= MOD_MASK_3CLICK;
  3073.     else if (orig_num_clicks == 4)
  3074. modifiers |= MOD_MASK_4CLICK;
  3075.     /* Add the modifier codes to our string */
  3076.     if (modifiers != 0)
  3077.     {
  3078. string[new_slen++] = K_SPECIAL;
  3079. string[new_slen++] = (int)KS_MODIFIER;
  3080. string[new_slen++] = modifiers;
  3081.     }
  3082.     /* Work out our pseudo mouse event */
  3083.     key_name[0] = (int)KS_EXTRA;
  3084.     key_name[1] = get_pseudo_mouse_code(current_button,
  3085.    is_click, is_drag);
  3086. }
  3087. #endif /* USE_MOUSE */
  3088. #ifdef USE_GUI
  3089. /*
  3090.  * If using the GUI, then we get menu and scrollbar events.
  3091.  *
  3092.  * A menu event is encoded as K_SPECIAL, KS_MENU, K_FILLER followed by
  3093.  * four bytes which are to be taken as a pointer to the GuiMenu
  3094.  * structure.
  3095.  *
  3096.  * A scrollbar event is K_SPECIAL, KS_SCROLLBAR, K_FILLER followed by
  3097.  * one byte representing the scrollbar number, and then four bytes
  3098.  * representing a long_u which is the new value of the scrollbar.
  3099.  *
  3100.  * A horizontal scrollbar event is K_SPECIAL, KS_HORIZ_SCROLLBAR,
  3101.  * K_FILLER followed by four bytes representing a long_u which is the
  3102.  * new value of the scrollbar.
  3103.  */
  3104. else if (key_name[0] == (int)KS_MENU)
  3105. {
  3106.     num_bytes = get_long_from_buf(tp + slen, &val);
  3107.     if (num_bytes == -1)
  3108. return -1;
  3109.     current_menu = (GuiMenu *)val;
  3110.     slen += num_bytes;
  3111. }
  3112. else if (key_name[0] == (int)KS_SCROLLBAR)
  3113. {
  3114.     /* Get the last scrollbar event in the queue of the same type */
  3115.     j = 0;
  3116.     for (i = 0; tp[j] == CSI && tp[j+1] == KS_SCROLLBAR
  3117.     && tp[j+2] != NUL; ++i)
  3118.     {
  3119. j += 3;
  3120. num_bytes = get_bytes_from_buf(tp + j, bytes, 1);
  3121. if (num_bytes == -1)
  3122.     break;
  3123. if (i == 0)
  3124.     current_scrollbar = (int)bytes[0];
  3125. else if (current_scrollbar != (int)bytes[0])
  3126.     break;
  3127. j += num_bytes;
  3128. num_bytes = get_long_from_buf(tp + j, &val);
  3129. if (num_bytes == -1)
  3130.     break;
  3131. scrollbar_value = val;
  3132. j += num_bytes;
  3133. slen = j;
  3134.     }
  3135.     if (i == 0) /* not enough characters to make one */
  3136. return -1;
  3137. }
  3138. else if (key_name[0] == (int)KS_HORIZ_SCROLLBAR)
  3139. {
  3140.     /* Get the last horiz. scrollbar event in the queue */
  3141.     j = 0;
  3142.     for (i = 0; tp[j] == CSI && tp[j+1] == KS_HORIZ_SCROLLBAR
  3143.        && tp[j+2] != NUL; ++i)
  3144.     {
  3145. j += 3;
  3146. num_bytes = get_long_from_buf(tp + j, &val);
  3147. if (num_bytes == -1)
  3148.     break;
  3149. scrollbar_value = val;
  3150. j += num_bytes;
  3151. slen = j;
  3152.     }
  3153.     if (i == 0) /* not enough characters to make one */
  3154. return -1;
  3155. }
  3156. #endif /* USE_GUI */
  3157. /* Finally, add the special key code to our string */
  3158. if (key_name[1] == NUL)
  3159.     string[new_slen++] = key_name[0]; /* from ":set <M-b>=xx" */
  3160. else
  3161. {
  3162.     string[new_slen++] = K_SPECIAL;
  3163.     string[new_slen++] = key_name[0];
  3164.     string[new_slen++] = key_name[1];
  3165. }
  3166. string[new_slen] = NUL;
  3167. extra = new_slen - slen;
  3168. if (extra < 0)
  3169. /* remove matched chars, taking care of noremap */
  3170.     del_typebuf(-extra, offset);
  3171. else if (extra > 0)
  3172. /* insert the extra space we need */
  3173.     ins_typebuf(string + slen, FALSE, offset, FALSE);
  3174. /*
  3175.  * Careful: del_typebuf() and ins_typebuf() may have
  3176.  * reallocated typebuf[]
  3177.  */
  3178. mch_memmove(typebuf + typeoff + offset, string, (size_t)new_slen);
  3179. return (len + extra + offset);
  3180.     }
  3181.     return 0;     /* no match found */
  3182. }
  3183. /*
  3184.  * Replace any terminal code strings in from[] with the equivalent internal
  3185.  * vim representation. This is used for the "from" and "to" part of a
  3186.  * mapping, and the "to" part of a menu command.
  3187.  * Any strings like "<C-UP>" are also replaced, unless 'cpoptions' contains
  3188.  * '<'.
  3189.  * K_SPECIAL by itself is replaced by K_SPECIAL KS_SPECIAL K_FILLER.
  3190.  *
  3191.  * The replacement is done in result[] and finally copied into allocated
  3192.  * memory. If this all works well *bufp is set to the allocated memory and a
  3193.  * pointer to it is returned. If something fails *bufp is set to NULL and from
  3194.  * is returned.
  3195.  *
  3196.  * CTRL-V characters are removed.  When "from_part" is TRUE, a trailing CTRL-V
  3197.  * is included, otherwise it is removed (for ":map xx ^V", maps xx to
  3198.  * nothing).  When 'cpoptions' does not contain 'B', a backslash can be used
  3199.  * instead of a CTRL-V.
  3200.  */
  3201.     char_u  *
  3202. replace_termcodes(from, bufp, from_part, do_lt)
  3203.     char_u *from;
  3204.     char_u **bufp;
  3205.     int from_part;
  3206.     int do_lt; /* also translate <lt> */
  3207. {
  3208.     int i;
  3209.     int slen;
  3210.     int key;
  3211.     int dlen = 0;
  3212.     char_u *src;
  3213.     int do_backslash; /* backslash is a special character */
  3214.     int do_special; /* recognize <> key codes */
  3215.     int do_key_code; /* recognize raw key codes */
  3216.     char_u *result; /* buffer for resulting string */
  3217.     do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
  3218.     do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL);
  3219.     do_key_code = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
  3220.     /*
  3221.      * Allocate space for the translation.  Worst case a single character is
  3222.      * replaced by 6 bytes (shifted special key), plus a NUL at the end.
  3223.      */
  3224.     result = alloc((unsigned)STRLEN(from) * 6 + 1);
  3225.     if (result == NULL) /* out of memory */
  3226.     {
  3227. *bufp = NULL;
  3228. return from;
  3229.     }
  3230.     src = from;
  3231.     /*
  3232.      * Check for #n at start only: function key n
  3233.      */
  3234.     if (from_part && src[0] == '#' && isdigit(src[1]))     /* function key */
  3235.     {
  3236. result[dlen++] = K_SPECIAL;
  3237. result[dlen++] = 'k';
  3238. if (src[1] == '0')
  3239.     result[dlen++] = ';'; /* #0 is F10 is "k;" */
  3240. else
  3241.     result[dlen++] = src[1]; /* #3 is F3 is "k3" */
  3242. src += 2;
  3243.     }
  3244.     /*
  3245.      * Copy each byte from *from to result[dlen]
  3246.      */
  3247.     while (*src != NUL)
  3248.     {
  3249. /*
  3250.  * If 'cpoptions' does not contain '<', check for special key codes,
  3251.  * like "<C-S-MouseLeft>"
  3252.  */
  3253. if (do_special && (do_lt || STRNCMP(src, "<lt>", 4)))
  3254. {
  3255.     slen = trans_special(&src, result + dlen, TRUE);
  3256.     if (slen)
  3257.     {
  3258. dlen += slen;
  3259. continue;
  3260.     }
  3261. }
  3262. /*
  3263.  * If 'cpoptions' does not contain 'k', see if it's an actual key-code.
  3264.  * Note that this is also checked after replacing the <> form.
  3265.  * Single character codes are NOT replaced (e.g. ^H or DEL), because
  3266.  * it could be a character in the file.
  3267.  */
  3268. if (do_key_code)
  3269. {
  3270.     for (i = 0; i < tc_len; ++i)
  3271.     {
  3272. slen = termcodes[i].len;
  3273. if (slen > 1
  3274. && STRNCMP(termcodes[i].code, src, (size_t)slen) == 0)
  3275. {
  3276.     result[dlen++] = K_SPECIAL;
  3277.     result[dlen++] = termcodes[i].name[0];
  3278.     result[dlen++] = termcodes[i].name[1];
  3279.     src += slen;
  3280.     break;
  3281. }
  3282.     }
  3283.     /* If terminal code matched, continue after it. */
  3284.     if (i != tc_len)
  3285. continue;
  3286. }
  3287. /*
  3288.  * If the character is K_SPECIAL, replace it with K_SPECIAL KS_SPECIAL
  3289.  * K_FILLER.
  3290.  */
  3291. if (*src == K_SPECIAL)
  3292. {
  3293.     result[dlen++] = K_SPECIAL;
  3294.     result[dlen++] = (int)KS_SPECIAL;
  3295.     result[dlen++] = K_FILLER;
  3296.     ++src;
  3297.     continue;
  3298. }
  3299. /*
  3300.  * Remove CTRL-V and ignore the next character.
  3301.  * For "from" side the CTRL-V at the end is included, for the "to"
  3302.  * part it is removed.
  3303.  * If 'cpoptions' does not contain 'B', also accept a backslash.
  3304.  */
  3305. key = *src;
  3306. if (key == Ctrl('V') || (do_backslash && key == '\'))
  3307. {
  3308.     ++src; /* skip CTRL-V or backslash */
  3309.     if (*src == NUL)
  3310.     {
  3311. if (from_part)
  3312.     result[dlen++] = key;
  3313. break;
  3314.     }
  3315. }
  3316. result[dlen++] = *src++;
  3317.     }
  3318.     result[dlen] = NUL;
  3319.     /*
  3320.      * Copy the new string to allocated memory.
  3321.      * If this fails, just return from.
  3322.      */
  3323.     if ((*bufp = vim_strsave(result)) != NULL)
  3324. from = *bufp;
  3325.     vim_free(result);
  3326.     return from;
  3327. }
  3328. /*
  3329.  * Gather the first characters in the terminal key codes into a string.
  3330.  * Used to speed up check_termcode().
  3331.  */
  3332.     static void
  3333. gather_termleader()
  3334. {
  3335.     int     i;
  3336.     int     len = 0;
  3337. #ifdef USE_GUI
  3338.     if (gui.in_use)
  3339. termleader[len++] = CSI;    /* the GUI codes are not in termcodes[] */
  3340. #endif
  3341.     termleader[len] = NUL;
  3342.     for (i = 0; i < tc_len; ++i)
  3343. if (vim_strchr(termleader, termcodes[i].code[0]) == NULL)
  3344. {
  3345.     termleader[len++] = termcodes[i].code[0];
  3346.     termleader[len] = NUL;
  3347. }
  3348.     need_gather = FALSE;
  3349. }
  3350. /*
  3351.  * Show all termcodes (for ":set termcap")
  3352.  * This code looks a lot like showoptions(), but is different.
  3353.  */
  3354.     void
  3355. show_termcodes()
  3356. {
  3357.     int     col;
  3358.     int     *items;
  3359.     int     item_count;
  3360.     int     run;
  3361.     int     row, rows;
  3362.     int     cols;
  3363.     int     i;
  3364.     int     len;
  3365. #define INC 27     /* try to make three columns */
  3366. #define GAP 2     /* spaces between columns */
  3367.     if (tc_len == 0)     /* no terminal codes (must be GUI) */
  3368. return;
  3369.     items = (int *)alloc((unsigned)(sizeof(int) * tc_len));
  3370.     if (items == NULL)
  3371. return;
  3372.     /* Highlight title */
  3373.     MSG_PUTS_TITLE("n--- Terminal keys ---");
  3374.     /*
  3375.      * do the loop two times:
  3376.      * 1. display the short items (non-strings and short strings)
  3377.      * 2. display the long items (strings)
  3378.      */
  3379.     for (run = 1; run <= 2 && !got_int; ++run)
  3380.     {
  3381. /*
  3382.  * collect the items in items[]
  3383.  */
  3384. item_count = 0;
  3385. for (i = 0; i < tc_len; i++)
  3386. {
  3387.     len = show_one_termcode(termcodes[i].name,
  3388.     termcodes[i].code, FALSE);
  3389.     if ((len <= INC - GAP && run == 1) || (len > INC - GAP && run == 2))
  3390. items[item_count++] = i;
  3391. }
  3392. /*
  3393.  * display the items
  3394.  */
  3395. if (run == 1)
  3396. {
  3397.     cols = (Columns + GAP) / INC;
  3398.     if (cols == 0)
  3399. cols = 1;
  3400.     rows = (item_count + cols - 1) / cols;
  3401. }
  3402. else /* run == 2 */
  3403.     rows = item_count;
  3404. for (row = 0; row < rows && !got_int; ++row)
  3405. {
  3406.     msg_putchar('n'); /* go to next line */
  3407.     if (got_int) /* 'q' typed in more */
  3408. break;
  3409.     col = 0;
  3410.     for (i = row; i < item_count; i += rows)
  3411.     {
  3412. msg_col = col; /* make columns */
  3413. show_one_termcode(termcodes[items[i]].name,
  3414.       termcodes[items[i]].code, TRUE);
  3415. col += INC;
  3416.     }
  3417.     out_flush();
  3418.     ui_breakcheck();
  3419. }
  3420.     }
  3421.     vim_free(items);
  3422. }
  3423. /*
  3424.  * Show one termcode entry.
  3425.  * Output goes into IObuff[]
  3426.  */
  3427.     int
  3428. show_one_termcode(name, code, printit)
  3429.     char_u  *name;
  3430.     char_u  *code;
  3431.     int     printit;
  3432. {
  3433.     char_u *p;
  3434.     int len;
  3435.     if (name[0] > '~')
  3436.     {
  3437. IObuff[0] = ' ';
  3438. IObuff[1] = ' ';
  3439. IObuff[2] = ' ';
  3440. IObuff[3] = ' ';
  3441.     }
  3442.     else
  3443.     {
  3444. IObuff[0] = 't';
  3445. IObuff[1] = '_';
  3446. IObuff[2] = name[0];
  3447. IObuff[3] = name[1];
  3448.     }
  3449.     IObuff[4] = ' ';
  3450.     p = get_special_key_name(TERMCAP2KEY(name[0], name[1]), 0);
  3451.     if (p[1] != 't')
  3452. STRCPY(IObuff + 5, p);
  3453.     else
  3454. IObuff[5] = NUL;
  3455.     len = STRLEN(IObuff);
  3456.     do
  3457. IObuff[len++] = ' ';
  3458.     while (len < 17);
  3459.     IObuff[len] = NUL;
  3460.     if (code == NULL)
  3461. len += 4;
  3462.     else
  3463. len += vim_strsize(code);
  3464.     if (printit)
  3465.     {
  3466. msg_puts(IObuff);
  3467. if (code == NULL)
  3468.     msg_puts((char_u *)"NULL");
  3469. else
  3470.     msg_outtrans(code);
  3471.     }
  3472.     return len;
  3473. }
  3474. #if (defined(WIN32) && !defined(USE_GUI)) || defined(PROTO)
  3475. static char ksme_str[20];
  3476. static char ksmr_str[20];
  3477. static char ksmd_str[20];
  3478. /*
  3479.  * For Win32 console: update termcap codes for existing console attributes.
  3480.  */
  3481.     void
  3482. update_tcap(attr)
  3483.     int attr;
  3484. {
  3485.     struct builtin_term *p;
  3486.     p = find_builtin_term(DEFAULT_TERM);
  3487.     sprintf(ksme_str, "33|%dm", attr);
  3488.     sprintf(ksmd_str, "33|%dm", attr | 0x08);  /* FOREGROUND_INTENSITY */
  3489.     sprintf(ksmr_str, "33|%dm", ((attr & 0x0F) << 4) | ((attr & 0xF0) >> 4));
  3490.     while (p->bt_string != NULL)
  3491.     {
  3492.       if (p->bt_entry == (int)KS_ME)
  3493.   p->bt_string = &ksme_str[0];
  3494.       else if (p->bt_entry == (int)KS_MR)
  3495.   p->bt_string = &ksmr_str[0];
  3496.       else if (p->bt_entry == (int)KS_MD)
  3497.   p->bt_string = &ksmd_str[0];
  3498.       ++p;
  3499.     }
  3500. }
  3501. #endif