Parse terminfo u6 string

The absence of a %p marker is a quirk of ncurses: the terminfo compiler (tic) recognizes either terminfo (which uses %p1 to mark parameters) or termcap (which relies upon convention for the parameters). That would be a legal termcap expression. Since tic knows how to process a termcap expression, the string shown is "close enough" that there was no need to translate it further.

You can see what ncurses does using tput, e.g.,

tput u6 40 50

gives (note the reversal of parameters)

^[[51;41R

If the expression were given as

u6=\E[%i%p2%d;%p1%dR

it would have the same result.

The u6-u9 capabilities are an early extension documented in ncurses's terminal database:

# INTERPRETATION OF USER CAPABILITIES
#
# The System V Release 4 and XPG4 terminfo format defines ten string
# capabilities for use by applications, <u0>...<u9>.   In this file, we use
# certain of these capabilities to describe functions which are not covered
# by terminfo.  The mapping is as follows:
#
#       u9      terminal enquire string (equiv. to ANSI/ECMA-48 DA)
#       u8      terminal answerback description
#       u7      cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6)
#       u6      cursor position report (equiv. to ANSI/ECMA-48 CPR)
#
# The terminal enquire string <u9> should elicit an answerback response
# from the terminal.  Common values for <u9> will be ^E (on older ASCII
# terminals) or \E[c (on newer VT100/ANSI/ECMA-48-compatible terminals).
#
# The cursor position request (<u7>) string should elicit a cursor position
# report.  A typical value (for VT100 terminals) is \E[6n.
#
# The terminal answerback description (u8) must consist of an expected
# answerback string.  The string may contain the following scanf(3)-like
# escapes:
#
#       %c      Accept any character
#       %[...]  Accept any number of characters in the given set
#
# The cursor position report (<u6>) string must contain two scanf(3)-style
# %d format elements.  The first of these must correspond to the Y coordinate
# and the second to the %d.  If the string contains the sequence %i, it is
# taken as an instruction to decrement each value after reading it (this is
# the inverse sense from the cup string).  The typical CPR value is
# \E[%i%d;%dR (on VT100/ANSI/ECMA-48-compatible terminals).
#
# These capabilities are used by tack(1m), the terminfo action checker
# (distributed with ncurses 5.0).

Checking that last comment, tack exercises u8 and u9 but does nothing with u6 and u7.

The extension was added early in 1995:

# 9.3.4 (Wed Feb 22 19:27:34 EST 1995):
#       * Added correct acsc/smacs/rmacs strings for vt100 and xterm.
#       * Added u6/u7/u8/u9 capabilities.
#       * Added PCVT entry.

and while it is included in several entries for completeness (not many: there are 16 occurrences in 18,699 lines of terminfo.src), there are no well-known users of the feature. In fact, there is one place in ncurses where it could have been written to use it (some ifdef'd debugging code in the tty_update.c file), but that uses hard-coded escape sequences (marked as "ANSI compatible").

The reason for the absence of users would be:

  • inverting an arbitrary terminfo expression is harder than it may seem
  • xterm and similar terminals interpret these escape sequences

In ECMA-48, these are (u7) DSR (device status report) and (u6) CPR (active position report).


Ahha.

It is a special entry in the database. It gives the respond format to u7.

The response is <ESC>[Y;XR as in Y=row and X=column.

If u6 has %i, one should decrement the responded values.

Example:

  • u6=\E[%i%d;%dR
  • u7=\E[6n

Send u7.

  • Response for example: \E[48;13R.
  • Result:
    • Y = 48 - 1 = 47
    • X = 13 - 1 = 12.