Recent

Author Topic: Inverted colors in console with CRT in Linux  (Read 1466 times)

glorfin

  • Jr. Member
  • **
  • Posts: 61
Inverted colors in console with CRT in Linux
« on: May 06, 2018, 08:46:43 pm »
I am writing a console application and would like to highlight some output with inverted colors.
In Windows I could do it retrieving current colors with GetConsoleScreenBufferInfo and then exchanging them.
But it does not seem that standard way to find current console colors exists in Linux.

In general, on Linux one can use escape sequences to invert colors. However, escape sequences seem to be disabled if one uses CRT unit.

Code: Pascal  [Select]
  1. program Invert;
  2. begin
  3.   writeln(#27'[7mInverted'#27'[m');
  4. end.

produces output in inverted colors, but
Code: Pascal  [Select]
  1. program Invert;
  2. uses CRT;
  3. begin
  4.   GoToXY(2,2);
  5.   writeln(#27'[7mInverted'#27'[m');
  6. end.
writes with normal attributes.

So, is there any way to use CRT unit and write with inverted colors on linux console?

Thank you in advance!

BobS

  • Full Member
  • ***
  • Posts: 153
Re: Inverted colors in console with CRT in Linux
« Reply #1 on: June 10, 2019, 09:52:38 am »
This works for me:
Code: Pascal  [Select]
  1. program Project1;
  2. uses crt, Unix;
  3. var
  4.   Rever, Reset: String;
  5.   RtnCode: Longint;
  6. begin
  7.   Rever:='tput rev';  (*reverse foreground/background*)
  8.   Reset:='tput sgr0';
  9.   writeln ('hello world');
  10.   RtnCode:=fpSystem(Rever);
  11.   writeln ('reverse the world');
  12.   RtnCode:=fpSystem(Reset);
  13.   writeln ('back to normal')
  14. end.

Handoko

  • Hero Member
  • *****
  • Posts: 3152
  • My goal: build my own game engine using Lazarus
Re: Inverted colors in console with CRT in Linux
« Reply #2 on: June 10, 2019, 11:21:04 am »
@glorfin
Maybe you will be interested to try how to make it colorful and blinking:

https://forum.lazarus.freepascal.org/index.php/topic,42759.msg298690.html#msg298690

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7430
Re: Inverted colors in console with CRT in Linux
« Reply #3 on: June 10, 2019, 11:42:31 am »
Crt puts the console in raw mode, so escapes won't work.

The current colors are in "textattr" in lo hi format, so

var b : byte;
b:=textattr;
textattr:=b shr 4 + (b and 15) shl 4;

should go a long way.

Maybe you need to set them with textcolor/background though, on unix.
« Last Edit: June 10, 2019, 12:02:10 pm by marcov »

BobS

  • Full Member
  • ***
  • Posts: 153
Re: Inverted colors in console with CRT in Linux
« Reply #4 on: June 10, 2019, 11:59:40 am »
Some more fun playing around with the tput (which works well in bash too):
Code: Pascal  [Select]
  1. program consoleclrs;
  2. uses crt, Unix;
  3. var
  4.   Rever, Reset, Blink, UnderOn, UnderOff, Bold: String;
  5.   (*In the color strings 'F' means foreground, 'B' means background*)
  6.   BlackF, BlackB, BlueF, BlueB, CyanF, CyanB, GreenF, GreenB: String;
  7.   strx: String;
  8.   RtnCode: Longint;
  9.   x: integer;
  10. begin
  11.   (*colors can very depending on your terminal settings*)
  12.   Rever:='tput rev';  (*reverse foreground/background, use Reset to stop*)
  13.   Reset:='tput sgr0'; (*sets foreground/background to default colors*)
  14.   Blink:='tput blink'; (*causes text to blink, use Reset to stop*)
  15.   UnderOn :='tput smul'; (*start underline*)
  16.   UnderOff:='tput rmul'; (*stop underline*)
  17.   Bold:='tput bold'; (*bolds text, use Reset to stop*)
  18.  
  19.   BlackF:='tput setaf 0';
  20.   BlackB:='tput setab 0';
  21.   BlueF :='tput setaf 4';
  22.   BlueB :='tput setab 4';
  23.   CyanF :='tput setaf 6';
  24.   CyanB :='tput setab 6';
  25.   GreenF:='tput setaf 2';
  26.   GreenB:='tput setab 2';
  27.  
  28.   RtnCode:=fpSystem(BlueF);
  29.   writeln ('I''m blue on black');
  30.  
  31.   RtnCode:=fpSystem(Rever);
  32.   writeln ('I''m black on blue');
  33.  
  34.   RtnCode:=fpSystem(GreenF); (*since reverse is on green is the background*)
  35.   writeln ('I''m black on green');
  36.  
  37.   RtnCode:=fpSystem(Reset);
  38.   RtnCode:=fpSystem(GreenF);
  39.   RtnCode:=fpSystem(CyanB);
  40.   writeln ('I''m green on cyan');
  41.  
  42.   RtnCode:=fpSystem(Reset);
  43.   writeln ('I''m your default colors!');
  44.   writeln ('This is a test.');
  45.     (*note if the screen hasn't been cleared recently an odd color bar may appear to fill up the rest of this line
  46.       in the last bacground color; setting background to black does not fix this.  Subsequent lines do not have
  47.       this bug.*)
  48.  
  49.   Rtncode:=fpSystem(GreenF);
  50.   write ('I''m a ');
  51.   Rtncode:=fpSystem(Blink);
  52.   write ('surprise');
  53.   Rtncode:=fpSystem(Reset);
  54.   Rtncode:=fpSystem(GreenF);
  55.   writeln ('!');
  56.  
  57.   Rtncode:=fpSystem(CyanF);
  58.   write ('I''m ');
  59.   Rtncode:=fpSystem(UnderOn);
  60.   write ('underlined');
  61.   Rtncode:=fpSystem(UnderOff);
  62.   writeln ('!  But this is not.');
  63.  
  64.   RtnCode:=fpSystem(GreenF);
  65.   RtnCode:=fpSystem(Bold);
  66.   writeln ('I''m very bold!');
  67.  
  68.   (*display some of the colors available in your console. *)
  69.   for x:=1 to 100   (*number of colors available depends on your enviornment try up to 255 or even 65K*)
  70.      do begin
  71.         str(x,strx);
  72.         strx:='tput setaf '+strx;
  73.         RtnCode:=fpSystem(strx);
  74.         write (' Color ',x);
  75.      end;
  76.    writeln ('');
  77.  
  78. end.  
Edit:
Further testing shows that the tput bold command (and the dim command not show in this code) are not reliable.  Sometimes they work, sometimes nothing changes, and sometimes a different color is used...at least in 256 color mode.
However italics works on my console (terminal):
so try
Code: Pascal  [Select]
  1. const
  2.   ItalicsOn = 'tput sitm';
  3.   italicsOff = 'tput ritm';
  4. ...
  5. RtnCode:=fpSystem(ItalicsOn);
  6. Writeln('I''m in Italics.');
« Last Edit: June 12, 2019, 01:51:18 pm by BobS »