A developer recently sent in a question about how to query the current terminal foreground and background colors from an application, rather than by using the SET TERM command, which displays a number of the settings on the screen, e.g. ...
.SET TERM
Current terminal settings for TSKAAA are:
Terminal driver: PCTDVG
Baud rate: 19200
Terminal width: 80
Terminal height: 24
Foreground color: 6
Background color: 0
Beveling: Program control
Sys bg color None
Win bg color None
Win text color None
The question is interesting at multiple levels, not just for the basic "
how to do it" (which like so many other programming details has multiple answers), but also for the implied "
how to find it in the documentation". And it's a good excuse to review all of it together, which often leads to either improvements in the documentation, the understanding, or the code itself. So with advance apologies for not just answering the question, here we go...
Starting with the
how to do it, let's look at how SET.LIT does it. Since the A-Shell LIT commands are actually all written in ASB (A-Shell BASIC), unlike the AMOS versions which were written in assembler, anything a LIT command can do, your application can do the same way. We don't automatically distribute the source to the LITs (mainly to keep them standardized), but we're happy to release in on request. In any case, the way SET.LIT does it starts with this include at the top of the program:
++include'once ashinc:trmchr.bsi
The common include files in the ashinc: ersatz directory (normally [907,16]) are available from the
SOSLIB repository. Unlike most BSI modules (which contain only functions, or at least jump over any code so that including them at the top of a program doesn't cause them to inadvertently execute, this one is designed for fall-through execution, and thus must be at the top of the program)...
++include'once trmchr.map
xcall TRMCHR,TRMCHR'STATUS,TRMCHR'MAP
So in other words it just does an XCALL TRMCHR, which is the real secret to querying the TeRMinal CHaRacteristics. (If you knew that, you'd know how to find it in the doc, but unfortunately it's not obvious.)
XCALL TRMCHR takes two arguments -- a status variable and a structure containing the various characteristics / settings, both of which are mapped in the trmchr.map file. (Note that although the ++include statement doesn't specify the location of trmchr.map, it defaults to the location of the current source file (ashinc:trmchr.bsi). The map file contains:
++ifnmap TRMCHR'MAP
map1 TRMCHR'MAP
map2 TRMCHR'FLAGS,f,6 ! Terminal features
map2 TFEATS,f,6,@TRMCHR'FLAGS ! In the days of TFEATS.SBR ! Terminal features word
map2 TRMCHR'ROWS,f,6 ! No. rows
map2 TRMCHR'COLS,f,6 ! No. columns
map2 TRMCHR'COLORS,f,6 ! No. supported colours
map2 TRMCHR'FORE,f,6 ! Current foreground colour
map2 TRMCHR'BACK,f,6 ! Current background colour
map2 TRMCHR'WINROW,f,6 ! Rows in current window (dlg)
map2 TRMCHR'WINCOL,f,6 ! Columns in current window (dlg)
map2 TRMCHR'TSLSIZ,F,6 ! TDV Top status line size.
map2 TRMCHR'BSLSIZ,F,6 ! TDV Bottom status line size.
map2 TRMCHR'BSSSIZ,F,6 ! TDV Bottom shifted size.
map1 TRMCHR'STATUS,f,6 ! Returned status of TRMCHR call
map1 TD'BLF,f,6,2 ! Block fill
map1 TD'KID,f,6,4 ! has column insert/delete
map1 TD'CLR,f,6,8 ! Has colour capability
map1 TD'AMS,f,6,32 ! is an Alpha Micro terminal
map1 TD'CID,f,6,16384 ! Character insert/delete
map1 TD'LID,f,6,32768 ! Line insert/delete
map1 TD'PRT,f,6,65536
map1 TD'132,f,6,131072 ! has 80/132 column support
map1 TD'BOX,f,6,524288 ! Box drawing commands
map1 TD'MOD,f,6,1048576 ! Has 'mode' type attributes
map1 TD'PHR,f,6,2097152 ! Phineas T. Phart colour mode
map1 TD'NSP,f,6,4194304 ! No space attributes
map1 TD'VRC,f,6,8388608 ! Variable no. rows and columns
++endif
That's probably more than enough information, but just to complete the circle, here's the actual code with SET.LIT that displays the result of the terminal width, height and colors...
if (TRMCHR'FLAGS and TD'132) or (TRMCHR'FLAGS and TD'VRC) then
print " Terminal width: ";str(TRMCHR'COLS)
endif
if TRMCHR'FLAGS and TD'VRC then
print " Terminal height: ";str(TRMCHR'ROWS)
endif
if TRMCHR'FLAGS and TD'CLR then
print " Foreground color: ";str(TRMCHR'FORE)
print " Background color: ";str(TRMCHR'BACK)
endif
(The other details output by SET TERM come from the
MX_BEVEL and
MX_SYSBCLR xcalls.)
So that's one way to do it. But as you're probably thinking, it seems like a lot of stuff just to query a couple of terminal settings. To make these kinds of repetitive low-level tasks simpler to code, we've created many utility functions which encapsulate the messy details, making it easier to just get what you want with minimal coding. You can find the entire set in the
SOSFUNC repository (aka 907,010 within the SOSLIB repository). Tip: to help you find what you're looking for within that set of library functions, use the
FUNCIDX command.
The SOSFUNC:FNTRMCHR.BSI module contains the following handy functions:
! Fn'TRMCHR'Rows() - returns current # rows in terminal
! Fn'TRMCHR'Cols() - returns current # cols in terminal
! Fn'TRMCHR'Flags() - returns current flags (TD_xxx)
! Fn'TRMCHR'Fgc() - returns current foreground color # [101]
! Fn'TRMCHR'Bgc() - returns current background color # [101]
As it turns out, when I first looked this morning, the last two functions didn't exist, which was rather inconvenient for this discussion, but fortunately were very easy to add. (Which is another good reason to post questions like this on the Forum, as it often leads to gaps being filled in.)
So to complete this alternate
how to do it, all you need is to include the sosfunc:fntrmchr.bsi and then call the functions that return the details you want, e.g.
++include'once sosfunc:fntrmchr.bsi
? "Current foreground color: ";Fn'TRMCHR'Bgc()
? "Current background color: ";Fn'TRMCHR'Fgc()
As for the "
how to find it in the documentation", I'm afraid I don't have a good answer. Normally I would suggest using either the index or the keyword search to search, but although there are several hits for both "terminal" and "color", I'm not sure any of them lead to XCALL TRMCHR or the Fn'TRMCHR'xxx() functions. On the bright side, asking the question helps us improve the documentation. (Memo to Ty: let's add a couple of search and index terms that mention "querying terminal characteristics" and lead to TRMCHR.)