This is ../p/doc/info/gpc.info, produced by makeinfo version 4.0 from
gpc.texi.

INFO-DIR-SECTION GNU programming tools
START-INFO-DIR-ENTRY
* GPC: (gpc).                   The GNU Pascal Compiler.
END-INFO-DIR-ENTRY
INFO-DIR-SECTION Individual utilities
START-INFO-DIR-ENTRY
* GPC: (gpc)Invoking GPC.       The GNU Pascal Compiler.
END-INFO-DIR-ENTRY

   This file documents the GNU Pascal Compiler.

   Copyright (C) 1988-2002 Free Software Foundation, Inc.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the sections entitled "GNU General Public License", "The GNU
Project", "The GNU Manifesto" and "Funding for Free Software" are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the sections entitled "GNU General Public
License", "The GNU Project", "The GNU Manifesto" and "Funding for Free
Software" and this permission notice, may be included in translations
approved by the Free Software Foundation instead of in the original
English.


File: gpc.info,  Node: GPC Units,  Prev: Run Time System,  Up: Programming

Units included with GPC
=======================

   GPC distributions now include a number of useful Pascal units and a
complete set of BP compatibility units - except for the `Graph' unit
(which is currently distributed separately due to its license) and the
OOP stuff. The main use of these units is to provide a way to port BP
programs to GPC as easily as possible. Some of the units also implement
functionaliy not available otherwise.

   Most of the BP compatibility units - except `CRT' and `Printer' -
are merely meant to let programs written for BP compile with GPC as
easily as possible. They should not be used in newly written code, and
for code ported from BP to GPC, it is suggested to replace them
successively with the more powerful - and often easier to use -
alternatives that GPC's Run Time System (*note Run Time System::)
offers.

   The following sections describe all units included with GPC (besides
the `GPC' module which describes the interface to the Run Time System,
*Note Run Time System::).

* Menu:

* CRT::          BP compatibility: CRT & WinCRT, portable, with many extensions
* Dos::          BP compatibility: Dos
* DosUnix::      Overcome some differences between Dos and Unix
* FileUtils::    Higher level file and directory handling
* GMP::          Arithmetic with unlimited size and precision
* GPCUtil::      Turbo Power compatibility, etc.
* HeapMon::      Primitive heap checking
* Intl::         Internationalization
* MD5::          `MD5' Message Digests
* Overlay::      BP compatibility: Overlay
* Pipe::         Start a child process, connected with pipes, also on Dos
* Ports::        BP compatibility (partly): `Port', `PortW' arrays
* Printer::      BP compatibility: Printer, portable
* RegEx::        Regular Expression matching and substituting
* Strings::      BP compatibility: Strings
* StringUtils::  Higher level string handling
* System::       BP compatibility: System
* Trap::         Trap runtime errors
* Turbo3::       BP compatibility: Turbo3
* WinDos::       BP compatibility: WinDos


File: gpc.info,  Node: CRT,  Next: Dos,  Up: GPC Units

BP compatibility: CRT & WinCRT, portable, with many extensions
--------------------------------------------------------------

   The following listing contains the interface of the CRT unit.

   `CRT' is a `curses' based unit for text screen handling.  It is
compatible to BP's `CRT' unit, even in a lot of minor details like the
values of function key codes and includes some routines for
compatibility with TP5's `Win' unit as well as BP's `WinCrt' and Turbo
Power's `TPCrt' units, and some extensions.

   The unit has been extended by many functions that were lacking in
BP's unit and required assembler code or direct memory/port access to
be implemented under BP. The GPC version is now fully suited for
portable, real-world programming without any dirty tricks.

   The unit is also available as `WinCRT', completely identical to
`CRT'. The only purpose of this "feature" is to let programs written
for TPW or BP, with a `uses WinCRT' directive, compile without changes.
Unlike TPW/BP's `WinCRT' unit, GPC's unit is not crippled, compared to
`CRT'.

   To use this unit, you will need the `ncurses' (version 5.0 or newer)
or `PDCurses' library which can be found in
`http://www.gnu-pascal.de/libs/'.

     { CRT (Crt Replacement Tool)
       Portable BP compatible CRT unit for GPC with many extensions
     
       This unit is aware of terminal types. This means programs using
       this unit will work whether run locally or while being logged in
       remotely from a system with a completely different terminal type
       (as long as the appropriate terminfo entry is present on the
       system where the program is run).
     
       NOTES:
     
       - The CRT unit needs the ncurses and panel libraries which should
         be available for almost any system. For Dos systems, where
         ncurses is not available, it is configured to use the PDCurses
         and its panel library instead. On Unix systems with X11, it can
         also use PDCurses (xcurses) and xpanel to produce X11 programs.
         The advantage is that the program won't need an xterm with a
         valid terminfo entry, the output may look a little nicer and
         function keys work better than in an xterm, but the disadvantage
         is that it will only run under X. The ncurses and PDCurses
         libraries (including panel and xpanel, resp.) can be found in
         http://www.gnu-pascal.de/libs/
         (Note that ncurses is already installed on many Unix systems.)
         For ncurses, version 5.0 or newer is strongly recommended
         because older versions contain a bug that severely affects CRT
         programs.
     
         When an X11 version under Unix is wanted, give `-DX11' when
         compiling crt.pas and crtc.c (or when compiling crt.pas or a
         program that uses CRT with `--automake'). On pre-X11R6 systems,
         give `-DNOX11R6' additionally. You might also have to give the
         path to the X11 libraries with `-L', e.g. `-L /usr/X11/lib'.
     
       - A few features cannot be implemented in a portable way and are
         only available on some systems:
     
           Sound, NoSound 1)                  -----------------------.
           GetShiftState                      ------------------.    |
           TextMode etc. 2)                   -------------.    |    |
           CRTSavePreviousScreen              --------.    |    |    |
           Interrupt signal (Ctrl-C) handling ---.    |    |    |    |
                                                 |    |    |    |    |
         Linux/IA32 3) (terminal)                X    X 4) X 5) X 6) X 6)
         Other Unix (terminal)                   X    X 7) X 5) -    -
         Unix (X11 version)                      X    X    - 8) X    -
         Dos (DJGPP)                             X    X    X    X    X
         MS-Windows (Cygwin or mingw)            X    -    X 9) X    -
     
         Notes:
     
         1) If you define NO_CRT_DUMMY_SOUND while compiling CRT, you
            will get linking errors when your program tries to use
            Sound/NoSound on a platform where it's not supported (which
            is useful to detect at compile time if playing sound is a
            major task of your program). Otherwise, Sound/NoSound will
            simply do nothing (which is usually acceptable if the program
            uses these routines just for an occasional beep).
     
         2) Changing to monochrome modes works on all platforms. Changing
            the screen size only works on those indicated. However, even
            on the platforms not supported, the program will react to
            screen size changes by external means (e.g. changing the
            window size with the mouse if running in a GUI window or
            resizing a console or virtual terminal).
     
         3) Probably also on other processors, but I've had no chance to
            test this yet.
     
         4) Only on a local console with access permissions to the
            corresponding virtual console memory device or using the
            `crtscreen' utility (see crtscreen.c in the demos directory).
     
         5) Only if supported by an external command (e.g., in xterms and
            on local Linux consoles). The command to be called can be
            defined in the environment variable `RESIZETERM' (where the
            variables `columns' and `lines' in the command are set to the
            size wanted). If not set, the code will try `resize -s' in an
            xterm and otherwise `SVGATextMode' and `setfont'. For this to
            work, these utilities need to be present in the PATH or
            `/usr/sbin' or `/usr/local/sbin'. Furthermore, SVGATextMode
            and setfont require root permissions, either to the
            executable of the program compiled with CRT or to resizecons
            (called by setfont) or SVGATextMode. To allow the latter, do
            "chmod u+s `which resizecons`" and/or
            "chmod u+s `which SVGATextMode`", as root once, but only if
            you really want each user to be allowed to change the text
            mode.
     
         6) Only on local consoles.
     
         7) Some terminals only. Most xterms etc. support it as well as
            other terminals that support an "alternate screen" in the
            smcup/rmcup terminal capabilities.
     
         8) But the user can resize the window.
     
         9) Only with PDCurses, not with ncurses. Changing the number of
            screen *columns* doesn't work in a full-screen session.
     
       - When CRT is initialized (automatically or explicitly; see the
         comments for CRTInit), the screen is cleared, and at the end of
         the program, the cursor is placed at the bottom of the screen
         (curses behaviour).
     
       - All the other things (including most details like color and
         function key constants) are compatible with BP's CRT unit, and
         there are many extensions that BP's unit does not have.
     
       - When the screen size is changed by an external event (e.g.,
         resizing an xterm or changing the screen size from another VC
         under Linux), the virtual "function key" kbScreenSizeChanged is
         returned. Applications can use the virtual key to resize their
         windows. kbScreenSizeChanged will not be returned if the screen
         size change was initiated by the program itself (by using
         TextMode or SetScreenSize). Note that TextMode sets the current
         panel to the full screen size, sets the text attribute to the
         default and clears the window (BP compatibility), while
         SetScreenSize does not.
     
       - After the screen size has been changed, whether by using
         TextMode, SetScreenSize or by an external event, ScreenSize will
         return the new screen size. The current window and all panels
         will have been adjusted to the new screen size. This means, if
         their right or lower ends are outside the new screen size, the
         windows are moved to the left and/or top as far as necessary. If
         this is not enough, i.e., if they are wider/higher than the new
         screen size, they are shrinked to the total screen width/height.
         When the screen size is enlarged, window sizes are not changed,
         with one exception: Windows that extend through the whole screen
         width/height are enlarged to the whole new screen width/height
         (in particular, full-screen windows remain full-screen). This
         behaviour might not be optimal for all purposes, but you can
         always resize your windows in your application after the screen
         size change.
     
       - (ncurses only) The environment variable `ESCDELAY' specifies the
         number of milliseconds allowed between an `Esc' character and
         the rest of an escape sequence (default 1000). Setting it to a
         value too small can cause problems with programs not recognizing
         escape sequences such as function keys, especially over slow
         network connections. Setting it to a value too large can delay
         the recognition of an `ESC' key press notably. On local Linux
         consoles, e.g., 10 seems to be a good value.
     
       - When trying to write portable programs, don't rely on exactly
         the same look of your output and the availability of all the key
         combinations. Some kinds of terminals support only some of the
         display attributes and special characters, and usually not all
         of the keys declared are really available. Therefore, it's safer
         to provide the same function on different key combinations and
         to not use the more exotic ones.
     
       - CRT supports an additional modifier key (if present), called
         `Extra'. On DJGPP, it's the <Scroll Lock> key, under X11 it's
         the modifier #4, and on a local Linux console, it's the `CtrlL'
         modifier (value 64) which is unused on many keytabs and can be
         mapped to any key(s), e.g. to those keys on new keyboards with
         these ugly symbols waiting to be replaced by penguins (keycodes
         125 and 127) by inserting the following two lines into your
         /etc/default.keytab and reloading the keytab with `loadkeys'
         (you usually have to do this as root):
     
         keycode 125 = CtrlL
         keycode 127 = CtrlL
     
       Copyright (C) 1998-2002 Free Software Foundation, Inc.
     
       Author: Frank Heckenbach <frank@pascal.gnu.de>
     
       This file is part of GNU Pascal.
     
       GNU Pascal is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
       by the Free Software Foundation; either version 2, or (at your
       option) any later version.
     
       GNU Pascal is distributed in the hope that it will be useful, but
       WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
       General Public License for more details.
     
       You should have received a copy of the GNU General Public License
       along with GNU Pascal; see the file COPYING. If not, write to the
       Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
       02111-1307, USA.
     
       As a special exception, if you link this file with files compiled
       with a GNU compiler to produce an executable, this does not cause
       the resulting executable to be covered by the GNU General Public
       License. This exception does not however invalidate any other
       reasons why the executable file might be covered by the GNU
       General Public License.
     
       Please also note the license of the curses library used. }
     
     {$gnu-pascal,I-}
     {$if __GPC_RELEASE__ < 20010620}
     {$error This unit requires GPC release 20010620 or newer.}
     {$endif}
     
     unit {$ifdef THIS_IS_WINCRT} WinCRT {$else} CRT {$endif};
     
     interface
     
     uses GPC;
     
     const
       { CRT modes }
       BW40          = 0;            { 40x25 Black/White }
       CO40          = 1;            { 40x25 Color }
       BW80          = 2;            { 80x25 Black/White }
       CO80          = 3;            { 80x25 Color }
       Mono          = 7;            { 80x25 Black/White }
       Font8x8       = 256;          { Add-in for 80x43 or 80x50 mode }
     
       { Mode constants for Turbo Pascal 3.0 compatibility }
       C40           = CO40;
       C80           = CO80;
     
       { Foreground and background color constants }
       Black         = 0;
       Blue          = 1;
       Green         = 2;
       Cyan          = 3;
       Red           = 4;
       Magenta       = 5;
       Brown         = 6;
       LightGray     = 7;
     
       { Foreground color constants }
       DarkGray      = 8;
       LightBlue     = 9;
       LightGreen    = 10;
       LightCyan     = 11;
       LightRed      = 12;
       LightMagenta  = 13;
       Yellow        = 14;
       White         = 15;
     
       { Add-in for blinking }
       Blink         = 128;
     
     type
       TTextAttr = Byte;
     
     var
       { If False (default: True), catch interrupt signals (SIGINT;
         Ctrl-C), and other flow control characters as well as SIGTERM,
         SIGHUP and perhaps other signals }
       CheckBreak: Boolean = True; asmname 'crt_CheckBreak';
     
       { If True (default : False), replace Ctrl-Z by #0 in input }
       CheckEOF: Boolean = False; asmname 'crt_CheckEOF';
     
       { Ignored -- meaningless here }
       DirectVideo: Boolean = True;
     
       { Ignored -- curses or the terminal driver will take care of that
         when necessary }
       CheckSnow: Boolean = False;
     
       { Current (sic!) text mode }
       LastMode: Word = 3; asmname 'crt_LastMode';
     
       { Current text attribute }
       TextAttr: TTextAttr = 7; asmname 'crt_TextAttr';
     
       { Window upper left coordinates. *Obsolete*! Please see WindowMin
         below. }
       WindMin: Word = not Word (0); asmname 'crt_WindMin';
     
       { Window lower right coordinates. *Obsolete*! Please see WindowMax
         below. }
       WindMax: Word = not Word (0); asmname 'crt_WindMax';
     
     procedure AssignCRT (var F: Text);
     function  KeyPressed: Boolean; asmname 'crt_keypressed';
     function  ReadKey: Char; asmname 'crt_readkey';
     
     { Not effective on all platforms, see above. See also SetScreenSize
       and SetMonochrome. }
     procedure TextMode (Mode: Integer);
     
     procedure Window (x1, y1, x2, y2: Integer); asmname 'crt_window';
     procedure GotoXY (x, y: Integer); asmname 'crt_gotoxy';
     function  WhereX: Integer; asmname 'crt_wherex';
     function  WhereY: Integer; asmname 'crt_wherey';
     procedure ClrScr; asmname 'crt_clrscr';
     procedure ClrEOL; asmname 'crt_clreol';
     procedure InsLine; asmname 'crt_insline';
     procedure DelLine; asmname 'crt_delline';
     procedure TextColor (Color: TTextAttr);
     procedure TextBackground (Color: TTextAttr);
     procedure LowVideo;
     procedure HighVideo;
     procedure NormVideo;
     procedure Delay (MS: Word); asmname 'crt_delay';
     
     { Not available on all platforms, see above }
     procedure Sound (Hz: Word); asmname 'crt_sound';
     procedure NoSound; asmname 'crt_nosound';
     
     { =================== Extensions over BP's CRT =================== }
     
     { Initializes the CRT unit. Should be called before using any of
       CRT's routines.
     
       Note: For BP compatibility, CRT is initizalized automatically when
       (almost) any of its routines are used for the first time. In this
       case, some defaults are set to match BP more closely. In
       particular, the PC charset (see SetPCCharSet) is enabled then
       (disabled otherwise), and the update level (see SetCRTUpdate) is
       set to UpdateRegularly (UpdateWaitInput otherwise). This feature
       is meant for BP compatibility *only*. Don't rely on it when
       writing a new program. Use CRTInit then, and set the defaults to
       the values you want explicitly.
     
       SetCRTUpdate is one of those few routines which will not cause CRT
       to be initialized immediately, and a value set with it will
       survive both automatic and explicit initialization, so you can use
       it to set the update level without caring which way CRT will be
       initialized. (This does not apply to SetPCCharSet. Since it works
       on a per-panel basis, it has to initialize CRT first, so there is
       a panel to start with.)
     
       If you terminate the program before calling CRTInit or any routine
       that causes automatic initialization, curses will never be
       initialized, so e.g., the screen won't be cleared. This can be
       useful, e.g., to check the command line arguments (or anything
       else) and if there's a problem, write an error and abort. Just be
       sure to write the error to StdErr, not Output (because Output will
       be assigned to CRT, and therefore writing to Output will cause CRT
       to be initialized, and because errors belong to StdErr, anyway),
       and to call `RestoreTerminal (True)' before (just to be sure, in
       case some code -- perhaps added later, or hidden in the
       initialization of some unit -- does initialize CRT). }
     procedure CRTInit; asmname 'crt_init';
     
     { Changes the input and output file and the terminal description CRT
       uses. Only effective with ncurses, and only if called before CRT
       is initialized (automatically or explicitly; see the comments for
       CRTInit). If TerminalType is nil, the default will be used. If
       InputFile and/or OutputFile are Null, they remain unchanged. }
     procedure CRTSetTerminal (TerminalType: CString; var InputFile,
       OutputFile: AnyFile); asmname 'crt_SetTerminal';
     
     { If called, causes CRT to save the previous screen contents if
       possible (see the comments at the beginning of the unit), and
       restore them when calling RestoreTerminal (True). After
       RestoreTerminal (False), they're saved again, and at the end of
       the program, they're restored. Should be called before
       initializing CRT (using CRTInit or automatically), otherwise the
       previous screen contents may already have been overwritten. Note
       that on some terminals (e.g., xterms and similar), this is the
       default behaviour. Ignored under XCurses, because the program it
       uses its own window, anyway. }
     procedure CRTSavePreviousScreen; asmname 'crt_save_previous_screen';
     
     { Returns True if CRTSavePreviousScreen was called and is available.
       Note that CRTSavePreviousScreenWorks does not work reliably until
       CRT is initialized, while CRTSavePreviousScreen should be called
       before CRT is initialized. That's why they are two separate
       routines. }
     function  CRTSavePreviousScreenWorks: Boolean;
       asmname 'crt_save_previous_screen_works';
     
     { If CRT is initialized automatically, not via CRTInit, and
       CRTAutoInitProc is not nil, it will be called before actually
       initializing CRT. }
     var
       CRTAutoInitProc: procedure = nil; asmname 'crt_auto_init_proc';
     
     { Aborts with a runtime error saying that CRT was not initialized.
       If you set CRTAutoInitProc to this procedure, you can effectively
       disable CRT's automatic initialization. }
     procedure CRTNotInitialized; asmname 'crt_not_initialized';
     
     { Set terminal to shell or curses mode. An internal procedure
       registered by CRT via RegisterRestoreTerminal does this as well,
       so CRTSetCursesMode has to be called only in unusual situations,
       e.g. after executing a process that changes terminal modes, but
       does not restore them (e.g. because it crashed or was killed), and
       the process was not executed with the Execute routine, and
       RestoreTerminal was not called otherwise. If you set it to False
       temporarily, be sure to set it back to True before doing any
       further CRT operations, otherwise the result may be strange. }
     procedure CRTSetCursesMode (On: Boolean);
       asmname 'crt_set_curses_mode';
     
     { Do the same as `RestoreTerminal (True)', but also clear the screen
       after restoring the terminal (except for XCurses, because the
       program uses its own window, anyway). Does not restore and save
       again the previous screen contents if CRTSavePreviousScreen was
       called. }
     procedure RestoreTerminalClearCRT;
       asmname 'crt_RestoreTerminalClearCRT';
     
     { Keyboard and character graphics constants -- BP compatible! =:-}
     {$i crt.inc}
     
     var
       { Tells whether the XCurses version of CRT is used }
       XCRT: Boolean = {$ifdef XCURSES} True {$else} False {$endif};
       asmname 'crt_XCRT';
     
       { If True (default: False), the Beep procedure and writing #7 do a
         Flash instead }
       VisualBell: Boolean = False; asmname 'crt_VisualBell';
     
     type
       TKey = Word;
     
       TCursorShape = (CursorIgnored, CursorHidden, CursorNormal,
       CursorFat, CursorBlock);
     
       TCRTUpdate = (UpdateNever, UpdateWaitInput, UpdateInput,
                     UpdateRegularly, UpdateAlways);
     
       TPoint = record
         X, Y: Integer
       end;
     
       PCharAttr = ^TCharAttr;
       TCharAttr = record
         Ch       : Char;
         Attr     : TTextAttr;
         PCCharSet: Boolean
       end;
     
       PCharAttrs = ^TCharAttrs;
       TCharAttrs = array [1 .. MaxVarSize div SizeOf (TCharAttr)] of
       TCharAttr;
     
       TWindowXY = packed record
         {$ifdef __BYTES_BIG_ENDIAN__}
         Fill: Integer (BitSizeOf (Word) - 16);
         Y, X: Word (8)
         {$elif defined (__BYTES_LITTLE_ENDIAN__)}
         X, Y: Word (8);
         Fill: Integer (BitSizeOf (Word) - 16)
         {$else}
         {$error Endianness is not defined!}
         {$endif}
       end;
     
     { Make sure TWindowXY really has the same size as WindMin and
       WindMax. If not, compilation will abort here with `division by
       zero'. Otherwise, the value of the constant will always be 1, and
       is of no further interest. }
     const
       AssertTWindowXYSize = 1 / Ord ((SizeOf (TWindowXY) = SizeOf
       (WindMin)) and
                                      (SizeOf (TWindowXY) = SizeOf
       (WindMax)));
     
     var
       { Window upper and left coordinates. More comfortable to access
         than WindMin, but also *obsolete*. WindMin and WindowMin still
         work, but have the problem that they implicitly limit the window
         size to 255x255 characters. Though that's not really small for a
         text window, it's easily possible to create bigger ones (e.g. in
         an xterm with a small font, on a high resolution screen and/or
         extending over several virutal desktops). When using coordinates
         greater than 254, the corresponding bytes in WindowMin/WindowMax
         will be set to 254, so, e.g., programs which do
         `Inc (WindowMin.X)' will not fail quite as badly (but probably
         still fail). The routines Window and GetWindow use Integer
         coordinates, and don't suffer from any of these problems, so
         they should be used instead. }
       WindowMin: TWindowXY absolute WindMin;
     
       { Window lower right coordinates. More comfortable to access than
         WindMax, but also *obsolete* (see the comments for WindowMin).
         Use Window and GetWindow instead. }
       WindowMax: TWindowXY absolute WindMax;
     
       { The attribute set by NormVideo }
       NormAttr: TTextAttr = 7; asmname 'crt_NormAttr';
     
       { Tells whether the current mode is monochrome }
       IsMonochrome: Boolean = False; asmname 'crt_IsMonochrome';
     
       { This value can be set to a combination of the shFoo constants
         and will be ORed to the actual shift state returned by
         GetShiftState. This can be used to easily simulate shift keys on
         systems where they can't be accessed. }
       VirtualShiftState: Integer = 0; asmname 'crt_VirtualShiftState';
     
     { Returns the size of the screen. Note: In BP's WinCRT unit,
       ScreenSize is a variable. But since writing to it from a program
       is pointless, anyway, providing a function here should not cause
       any incompatibility. }
     function  ScreenSize: TPoint; asmname 'crt_GetScreenSize';
     
     { Change the screen size if possible. }
     procedure SetScreenSize (x, y: Integer);
       asmname 'crt_SetScreenSize';
     
     { Turns colors off or on. }
     procedure SetMonochrome (Monochrome: Boolean);
       asmname 'crt_SetMonochrome';
     
     { Tell which modifier keys are currently pressed. The result is a
       combination of the shFoo constants defined in crt.inc, or 0 on
       systems where this function is not supported -- but note
       VirtualShiftState. If supported, ReadKey automatically converts
       kbIns and kbDel keys to kbShIns and kbShDel, resp., if shift is
       pressed. }
     function  GetShiftState: Integer; asmname 'crt_getshiftstate';
     
     { Get the extent of the current window. Use this procedure rather
       than reading WindMin and WindMax or WindowMin and WindowMax, since
       this routine allows for window sizes larger than 255. The
       resulting coordinates are 1-based (like in Window, unlike WindMin,
       WindMax, WindowMin and WindowMax). Any of the parameters may be
       Null in case you're interested in only some of the coordinates. }
     procedure GetWindow (var x1, y1, x2, y2: Integer);
       asmname 'crt_getwindow';
     
     { Determine when to update the screen. The possible values are the
       following. The given conditions *guarantee* updates. However,
       updates may occur more frequently (even if the update level is set
       to UpdateNever). About the default value, see the comments for
       CRTInit.
     
       UpdateNever    : never (unless explicitly requested with
                        CRTUpdate)
       UpdateWaitInput: before Delay and CRT input, unless typeahead is
                        detected
       UpdateInput    : before Delay and CRT input
       UpdateRegularly: before Delay and CRT input and otherwise in
                        regular intervals without causing too much
                        refresh. This uses a timer on some systems
                        (currently, Unix with ncurses). This was created
                        for BP compatibility, but for many applications,
                        a lower value causes less flickering in the
                        output, and additionally, timer signals won't
                        disturb other operations. Under DJGPP, this
                        always updates immediately, but this fact should
                        not mislead DJGPP users into thinking this is
                        always so.
       UpdateAlways   : after each output. This can be very slow. (Not so
                        under DJGPP, but this fact should not mislead
                        DJGPP users ...) }
     procedure SetCRTUpdate (UpdateLevel: TCRTUpdate);
       asmname 'crt_setupdatelevel';
     
     { Do an update now, independently of the update level }
     procedure CRTUpdate; asmname 'crt_update_immediately';
     
     { Do an update now and completely redraw the screen }
     procedure CRTRedraw; asmname 'crt_redraw';
     
     { Return Ord (key) for normal keys and $100 * Ord (fkey) for
       function keys }
     function  ReadKeyWord: TKey; asmname 'crt_readkeyword';
     
     { Extract the character and scan code from a TKey value }
     function  Key2Char (k: TKey): Char;
     function  Key2Scan (k: TKey): Char;
     
     { Convert a key to upper/lower case if it is a letter, leave it
       unchanged otherwise }
     function  UpCaseKey (k: TKey): TKey;
     function  LoCaseKey (k: TKey): TKey;
     
     { Return key codes for the combination of the given key with Ctrl,
       Alt, AltGr or Extra, resp. Returns 0 if the combination is
       unknown. }
     function  CtrlKey  (ch: Char): TKey; asmname 'crt_ctrlkey';
     function  AltKey   (ch: Char): TKey; asmname 'crt_altkey';
     function  AltGrKey (ch: Char): TKey; asmname 'crt_altgrkey';
     function  ExtraKey (ch: Char): TKey; asmname 'crt_extrakey';
     
     { Check if k is a pseudo key generated by a deadly signal trapped }
     function  IsDeadlySignal (k: TKey): Boolean;
     
     { Produce a beep or a screen flash }
     procedure Beep; asmname 'crt_beep';
     procedure Flash; asmname 'crt_flash';
     
     { Get size of current window (calculated using GetWindow) }
     function  GetXMax: Integer;
     function  GetYMax: Integer;
     
     { Get/goto an absolute position }
     function  WhereXAbs: Integer;
     function  WhereYAbs: Integer;
     procedure GotoXYAbs (X, Y: Integer);
     
     { Turn scrolling on or off }
     procedure SetScroll (State: Boolean); asmname 'crt_setscroll';
     
     { Read back whether scrolling is enabled }
     function  GetScroll: Boolean; asmname 'crt_getscroll';
     
     { Determine whether to interpret non-ASCII characters as PC ROM
       characters (True), or in a system dependent way (False). About the
       default, see the comments for CRTInit. }
     procedure SetPCCharSet (PCCharSet: Boolean);
       asmname 'crt_setpccharset';
     
     { Read back the value set by SetPCCharSet }
     function  GetPCCharSet: Boolean; asmname 'crt_getpccharset';
     
     { Determine whether to interpret #7, #8, #10, #13 as control
       characters (True, default), or as graphics characters (False) }
     procedure SetControlChars (UseControlChars: Boolean);
       asmname 'crt_setcontrolchars';
     
     { Read back the value set by SetControlChars }
     function  GetControlChars: Boolean; asmname 'crt_getcontrolchars';
     
     procedure SetCursorShape (Shape: TCursorShape);
       asmname 'crt_setcursorshape';
     function  GetCursorShape: TCursorShape;
       asmname 'crt_getcursorshape';
     
     procedure HideCursor;
     procedure HiddenCursor;
     procedure NormalCursor;
     procedure FatCursor;
     procedure BlockCursor;
     procedure IgnoreCursor;
     
     { Simulates a block cursor by writing a block character onto the
       cursor position. The procedure automatically finds the topmost
       visible panel whose shape is not CursorIgnored and places the
       simulated cursor there (just like the hardware cursor), with
       matching attributes, if the cursor shape is CursorFat or
       CursorBlock (otherwise, no simulated cursor is shown).
     
       Calling this procedure again makes the simulated cursor disappear.
       In particular, to get the effect of a blinking cursor, you have to
       call the procedure repeatedly (say, 8 times a second). CRT will
       not do this for you, since it does not intend to be your main
       event loop. }
     procedure SimulateBlockCursor; asmname 'crt_SimulateBlockCursor';
     
     { Makes the cursor simulated by SimulateBlockCursor disappear if it
       is active. Does nothing otherwise. You should call this procedure
       after using SimulateBlockCursor before doing any further CRT
       output (though failing to do so should not hurt except for
       possibly leaving the simulated cursor in its old position longer
       than it should). }
     procedure SimulateBlockCursorOff;
       asmname 'crt_SimulateBlockCursorOff';
     
     function  GetTextColor: Integer;
     function  GetTextBackground: Integer;
     
     { Write string at the given position without moving the cursor.
       Truncated at the right margin. }
     procedure WriteStrAt (x, y: Integer; const s: String; Attr:
       TTextAttr);
     
     { Write (several copies of) a char at then given position without
       moving the cursor. Truncated at the right margin. }
     procedure WriteCharAt (x, y, Count: Integer; Ch: Char; Attr:
       TTextAttr);
     
     { Write characters with specified attributes at the given position
       without moving the cursor. Truncated at the right margin. }
     procedure WriteCharAttrAt (x, y, Count: Integer; CharAttr:
       PCharAttrs); asmname 'crt_writecharattrat';
     
     { Write a char while moving the cursor }
     procedure WriteChar (Ch: Char);
     
     { Read a character from a screen position }
     procedure ReadChar (x, y: Integer; var Ch: Char; var Attr:
       TTextAttr); asmname 'crt_readchar';
     
     { Change only text attributes, leave characters. Truncated at the
       right margin. }
     procedure ChangeTextAttr (x, y, Count: Integer; NewAttr: TTextAttr);
     
     { Fill current window }
     procedure FillWin (Ch: Char; Attr: TTextAttr);
       asmname 'crt_fillwin';
     
     { Calculate size of memory required for ReadWin in current window. }
     function  WinSize: SizeType; asmname 'crt_winsize';
     
     { Save window contents. Buf must be WinSize bytes large. }
     procedure ReadWin (var Buf); asmname 'crt_readwin';
     
     { Restore window contents saved by ReadWin. The size of the current
       window must match the size of the window from which ReadWin was
       used, but the position may be different. }
     procedure WriteWin (const Buf); asmname 'crt_writewin';
     
     type
       WinState = record
         x1, y1, x2, y2, WhereX, WhereY, NewX1, NewY1, NewX2, NewY2:
       Integer;
         TextAttr: TTextAttr;
         CursorShape: TCursorShape;
         ScreenSize: TPoint;
         Buffer: ^Byte
       end;
     
     { Save window position and size, cursor position, text attribute and
       cursor shape -- *not* the window contents. }
     procedure SaveWin (var State: WinState);
     
     { Make a new window (like Window), and save the contents of the
       screen below the window as well as the position and size, cursor
       position, text attribute and cursor shape of the old window. }
     procedure MakeWin (var State: WinState; x1, y1, x2, y2: Integer);
     
     { Create window in full size, save previous text mode and all values
       that MakeWin does. }
     procedure SaveScreen (var State: WinState);
     
     { Restore the data saved by SaveWin, MakeWin or SaveScreen. }
     procedure RestoreWin (var State: WinState);
     
     { Panels }
     
     type
       TPanel = Pointer;
     
     function  GetActivePanel: TPanel; asmname 'crt_GetActivePanel';
     procedure PanelNew                 (x1, y1, x2, y2: Integer;
       BindToBackground: Boolean); asmname 'crt_PanelNew';
     procedure PanelDelete              (Panel: TPanel);
       asmname 'crt_PanelDelete';
     procedure PanelBindToBackground    (Panel: TPanel; BindToBackground:
       Boolean); asmname 'crt_PanelBindToBackground';
     function  PanelIsBoundToBackground (Panel: TPanel): Boolean;
       asmname 'crt_PanelIsBoundToBackground';
     procedure PanelActivate            (Panel: TPanel);
       asmname 'crt_PanelActivate';
     procedure PanelHide                (Panel: TPanel);
       asmname 'crt_PanelHide';
     procedure PanelShow                (Panel: TPanel);
       asmname 'crt_PanelShow';
     function  PanelHidden              (Panel: TPanel): Boolean;
       asmname 'crt_PanelHidden';
     procedure PanelTop                 (Panel: TPanel);
       asmname 'crt_PanelTop';
     procedure PanelBottom              (Panel: TPanel);
       asmname 'crt_PanelBottom';
     procedure PanelMoveAbove           (Panel, Above: TPanel);
       asmname 'crt_PanelMoveAbove';
     procedure PanelMoveBelow           (Panel, Below: TPanel);
       asmname 'crt_PanelMoveBelow';
     function  PanelAbove               (Panel: TPanel): TPanel;
       asmname 'crt_PanelAbove';
     function  PanelBelow               (Panel: TPanel): TPanel;
       asmname 'crt_PanelBelow';
     
     { TPCRT compatibility }
     
     { Write a string at the given position without moving the cursor.
       Truncated at the right margin. }
     procedure WriteString (const s: String; y, x: Integer);
     
     { Write a string at the given position with the given attribute
       without moving the cursor. Truncated at the right margin. }
     procedure FastWriteWindow (const s: String; y, x: Integer; Attr:
       TTextAttr);
     
     { Write a string at the given absolute position with the given
       attribute without moving the cursor. Truncated at the right
       margin. }
     procedure FastWrite       (const s: String; y, x: Integer; Attr:
       TTextAttr);
     
     { WinCrt compatibility }
     
     const
       cw_UseDefault = Integer ($8000);
     
     var
       WindowOrg : TPoint = (cw_UseDefault, cw_UseDefault);  { Ignored }
       WindowSize: TPoint = (cw_UseDefault, cw_UseDefault);  { Ignored }
       Cursor    : TPoint = (0, 0);  { Cursor location, 0-based }
       asmname 'crt_cursor_pos';
       Origin    : TPoint = (0, 0);  { Ignored }
       InactiveTitle: PChar = '(Inactive %s)';  { Ignored }
       AutoTracking: Boolean = True;  { Ignored }
       WindowTitle: {$ifdef __BP_TYPE_SIZES__}
                    array [0 .. 79] of Char
                    {$else}
                    TStringBuf
                    {$endif};  { CRT window title, ignored }
     
     procedure InitWinCrt; asmname 'crt_initwincrt';
     
     { Halts the program }
     procedure DoneWinCrt; attribute (noreturn);
       asmname 'crt_donewincrt';
     
     procedure WriteBuf (Buffer: PChar; Count: SizeType);
       asmname 'crt_writebuf';
     
     function  ReadBuf (Buffer: PChar; Count: SizeType): SizeType;
       asmname 'crt_readbuf';
     
     { 0-based coordinates! }
     procedure CursorTo (x, y: Integer); asmname 'crt_cursorto';
     
     { Dummy }
     procedure ScrollTo (x, y: Integer); asmname 'crt_scrollto';
     
     { Dummy }
     procedure TrackCursor; asmname 'crt_trackcursor';

