The test program below (kempbug1.pas) shows how one can import CRT to use the keystroke processing not available in Standard Pascal (e.g. function Keypressed and ReadKeyWord), yet re-assign 'output' so that it bypasses CRT and continues to use standard output. (Thanks to Frank for this suggestion.)
Thus, you can use CRT for input, while using escape sequences on standard output. This is useful only in particular circumstances, for example, if you require terminal-specific escape sequences not supported by ncurses and you are willing to either limit your program to those terminals or have your program detect terminal type and make adjustments before calling ncurses/CRT.
This was tested on Mac OSX, using the standard OSX terminal emulator (which implements most of a vt102).
Willett Kempton wrote:
What I meant by 'disturbs' is that if I IMPORT CRT, then try to write a direct screen-control escape sequence, it doesn't work. ... the esc gets changed to "<". What am I missing?
Frank Heckenbach wrote:
CRT redirects `Output'. You can, however, assign a `Text' variable (including `Output' if you like) to '' (empty string) or '-', meaning standard output directly, and write to it.
But it still won't play well with curses since curses then has a wrong idea of the cursor position, and when it next updates the screen, it will overwrite your characters.
You could try doing input via CRT and all output directly, but I'm not sure if this works well (never needed to).
Yes it works! In the process I discovered two problems, tentatively labelled bugs:
bug 1: The "assign/rewrite" of the predeclared file output works alright if followed by the GPC-imported call "sleep" (or possibly other calls) but without it, no subsequent output appears on standard output (or at least not on the screen). A call to CRTInit rather than sleep does NOT fix the problem. Using another non-predeclared text file variable rather than output does not fix the problem.
bug 2: After the assign/rewrite, the predeclared procedure writeln does just a LF, not a CR. To get normal output, one has to manually write the CR, e.g. write(chr(13)). I understand that this is happening because output is being treated as a text file, but either 'rewrite' should be smarter about recognizing standard output, or there should be some optional field of BindingType so the programmer can tell writeln to keep using.
I'm not capable of developing a patch to the runtimes, but I would be glad to volunteer to write or edit documentation, given some guidance as to what would be helpful.
Willett Kempton Visible Software
------------------------------------------------------------------------ -------------------------------------------
program kempbug1(input,output); { This program shows how to use standard output for "write", and do escape sequences } { directly, even those not in ncurses, while using the CRT package for input. } { Two problems are illustrated in this test program: see BUG1 and BUG2 in main prog. }
import GPC only (sleep,SleepMicroSeconds); CRT; { import direct keyboard input, but redirect output so it's not affected }
type attributes = ( none, bold, x2,x3, underscore, ansiblink, x6, reverse); (* the ordinal values of the above are the ANSI screen codes. *) attset = set of attributes;
procedure writelncon; { send LF CR to output, a workaround for bug } begin write(chr(10),chr(13)); end;
procedure SetAttributes( att : attset); (* set ANSI attributes for subsequent write *) const esc = 27; var a: attributes; begin for a:= none to reverse do if a in att then write(output,chr(esc),'[',ord(a):1,'m'); end;
procedure big; (* vt102-specific escape codes: write in big letters. *) (* code is: esc, poundsign, 3 for top; esc, poundsign, 4 for bottom *) var i: 3..4; begin for i:= 3 to 4 do begin write(chr(27),chr(35), i:1,'Big letters'); writelncon { bug workaround } end; end;
procedure ansiline; { a line testing ANSI attributes } begin write('normal'); setattributes([bold]); write('bold'); setattributes([none,underscore]); write('underscore'); setattributes([ none]); write('normal'); end;
begin (* kempbug1 *) writeln(output, 'writeln to output, with CRT package'); ansiline; { ANSI escape sequences do NOT work with output via CRT } writeln; writeln('preparing to assign(output,'''');'); rewrite(output,''); (* eliminate GPC redirection of 'output' *) sleep(1); { BUG 1: if this sleep is not done, subsequent output is not visible! } writeln( 'writeln to output after assign(output'''')'); writeln('another writeln, should begin at left margin'); { BUG 2: only LF, no CR from writeln } writelncon; ansiline; writelncon; write('next try vt102 big letters (just a double-line on non-vt terminals)'); writelncon; big; { escape sequences work correctly even though not in ncurses } end (* kempbug1 *).