1
0
mirror of https://github.com/gdamore/tcell.git synced 2025-05-08 19:29:47 +08:00
tcell/terminfo
Graham Clark 2d6d7fbe48 Change interpretation of pushing quoted character in terminfo parser
I noticed this problem while running a gowid test program (palette.go)
with TERM=xterm-16color. This terminal type is not present in tcell's
built-in database, and so tcell falls back to the dynamic terminal type
by parsing the output of infocmp. The symptom was that foreground colors
were not correctly set, leaving a monochrome screen. This seems to be
caused by a problem interpreting the *background* color terminfo
rule. The attribute to set background color is defined like this (Ubuntu
20.04):

$ infocmp xterm-16color | grep setab
	setab=\E[%?%p1%{8}%<%t%p1%'('%+%e%p1%{92}%+%;%dm,

The middle sections says "if p1<8 then push(p1+'(') ". '(' is ascii
40. If I run

$ tput setab 5

the terminal sees 'ESC[45m'. This correctly sets the background color to
magenta. But if I tell tcell to emit a cell with background color set to
tcell.Color(5), the terminal sees 'ESC[0m'. This means in practice, my
app emits a code to set the foreground color, then an SGR code that
resets all attributes, then the ASCII character.

When tcell "runs" a terminfo rule in terminfo::TParm(), a push to the
stack preserves the type of the argument pushed - int or string. When a
single quote is encountered, the argument within is pushed to the stack
as a string. For the `setab` rule above, tcell will then pop as an int,
discarding the error and returning 0. The fix here is to have tcell push
the argument inside the single quotes as an integer, using the ascii
value of the argument e.g. "(" -> 40 - and assume the string is length
1, I suppose. Cross-referencing against
ncurses/tinfo/lib_tinfo.c::tparam_internal(), it looks like this code
assumes a single-quoted string is assumed to be length=1 and is also
interpreted as an integer with the ascii value of the character:

case S_QUOTE:
    cp++;
    npush(UChar(*cp));
    cp++;
    break;
2020-09-20 08:17:17 -07:00
..
2020-08-31 08:55:31 -07:00
2020-08-30 22:57:00 -07:00
2020-08-25 16:20:58 -07:00
2020-08-30 22:57:00 -07:00
2020-08-30 22:57:00 -07:00
2020-08-25 16:20:58 -07:00
2020-08-30 22:57:00 -07:00
2020-08-30 22:57:00 -07:00
2020-08-31 08:55:31 -07:00
2020-08-30 22:57:00 -07:00
2020-08-30 22:57:00 -07:00
2020-08-30 22:57:00 -07:00
2020-08-31 08:55:31 -07:00
2020-08-31 08:55:31 -07:00
2020-08-25 16:20:58 -07:00
2020-08-31 08:55:31 -07:00
2017-11-24 13:13:06 -08:00
2020-08-31 08:55:31 -07:00
2019-07-29 22:47:04 -07:00
2017-11-24 13:13:06 -08:00

This package represents the parent for all terminals.

In older versions of tcell we had (a couple of) different external file formats for the terminal database. Those are now removed. All terminal definitions are supplied by one of two methods:

  1. Compiled Go code

  2. For systems with terminfo and infocmp, dynamically generated at runtime.

The Go code can be generated using the mkinfo utility in this directory. The database entry should be generated into a package in a directory named as the first character of the package name. (This permits us to group them all without having a huge directory of little packages.)

It may be desirable to add new packages to the extended package, or -- rarely -- the base package.

Applications which want to have the large set of terminal descriptions built into the binary can simply import the extended package. Otherwise a smaller reasonable default set (the base package) will be included instead.