This is 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, 1996-2000 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
* 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
`ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/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
       ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/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/x86 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.
     
     Copyright (C) 1998-2000 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}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 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 in this context }
       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)
         {$else}
         X, Y : Word (8);
         Fill : Integer (BitSizeOf (Word) - 16)
         {$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 or
       Alt, resp. Returns 0 if the combination is unknown. }
     function  CtrlKey (ch : Char) : TKey; asmname 'crt_ctrlkey';
     function  AltKey  (ch : Char) : TKey; asmname 'crt_altkey';
     
     { 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; 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; Bind : 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';


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

BP compatibility: Dos
---------------------

   The following listing contains the interface of the Dos unit.

   This is a portable implementation of most routines from BP's `Dos'
unit. A few routines that are Dos - or even x86 real mode - specific,
are only available if `__BP_UNPORTABLE_ROUTINES__' is defined, *Note BP
Incompatibilities::.

   The same functionality and much more is available in the Run Time
System, *Note Run Time System::. In some cases, the RTS routines have
the same interface as the routines in this unit (e.g.  `GetEnv',
`FSplit', `FExpand', `FSearch'), in other cases, they have different
names and/or easier and less limiting interfaces (e.g. `ReadDir' etc.
vs. `FindFirst' etc.), and are often more efficient.

   Therefore, using this unit is not recommended in newly written
programs.

     {
     Portable BP compatible Dos unit
     
     This unit supports most of the routines and declarations of BP's Dos
     unit.
     
     NOTES:
     
     - The procedures Keep, GetIntVec, SetIntVec are not supported since
       they make only sense for Dos real-mode programs (and GPC compiled
       programs do not run in real-mode, even on x86 under Dos). The
       procedures Intr and MsDos are only supported under DJGPP if
       `__BP_UNPORTABLE_ROUTINES__' is defined (with the
       `-D__BP_UNPORTABLE_ROUTINES__' option). A few other routines are
       also only supported with this define, but on all platforms (but
       they are crude hacks, that's why they are not supported without
       this define).
     
     - The internal structure of file variables (FileRec and TextRec) is
       different in GPC. However, as far as TFDDs are concerned, there
       are other ways to achieve the same in GPC, see the GPC unit.
     
     Copyright (C) 1998-2000 Free Software Foundation, Inc.
     
     Authors: Frank Heckenbach <frank@pascal.gnu.de>
              Prof. Abimbola A. Olowofoyeku <African_Chief@bigfoot.com>
     
     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.
     }
     
     {$gnu-pascal}
     {$if __GPC_RELEASE__ < 20000412}
     {$error This unit requires GPC release 20000412 or newer.}
     {$endif}
     
     unit Dos;
     
     interface
     
     uses GPC, System;
     
     type
       Byte8 = Cardinal (8);
       TDosAttr = Word;
       GPC_AnyFile = AnyFile; { in order to have AnyFile parameters,
                                while AnyFile is redefined below }
     
     const
       { File attribute constants }
       ReadOnly      = $01;
       Hidden        = $02; { set for dot files except '.' and '..' }
       SysFile       = $04; { not supported }
       VolumeID      = $08; { not supported }
       Directory     = $10;
       Archive       = $20; { means: not executable }
       {$local W-} AnyFile = $3f; {$endlocal}
     
       { Flag bit masks -- only used by the unportable Dos routines }
       FCarry     = 1;
       FParity    = 4;
       FAuxiliary = $10;
       FZero      = $40;
       FSign      = $80;
       FOverflow  = $800;
     
       { DosError codes }
       DosError_FileNotFound = 2;
       DosError_PathNotFound = 3;
       DosError_AccessDenied = 5;
       DosError_InvalidMem   = 9;
       DosErorr_InvalidEnv   = 10;
       DosError_NoMoreFiles  = 18;
       DosError_IOError      = 29;
       DosError_ReadFault    = 30;
     
     type
       { String types. Not used in this unit, but declared for
         compatibility. }
       ComStr  = String [127];        { Command line string }
       PathStr = String [79];         { File pathname string }
       DirStr  = String [67];         { Drive and directory string }
       NameStr = String [8];          { File name string }
       ExtStr  = String [4];          { File extension string }
     
       TextBuf = array [0 .. 127] of Char;
     
       { Search record used by FindFirst and FindNext }
       SearchRecFill = packed array [1 .. 21] of Byte8;
       SearchRec = {$ifdef __BP_TYPE_SIZES__} packed {$endif} record
         Fill : SearchRecFill;
         Attr : Byte8;
         Time, Size : LongInt;
         Name : {$ifdef __BP_TYPE_SIZES__}
                String [12]
                {$else}
                TString
                {$endif}
       end;
     
       { Date and time record used by PackTime and UnpackTime }
       DateTime = record
         Year, Month, Day, Hour, Min, Sec : Word
       end;
     
       { 8086 CPU registers -- only used by the unportable Dos routines }
       Registers = record
       case Boolean of
         False : (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Word16);
         True  : (AL, AH, BL, BH, CL, CH, DL, DH : Byte8)
       end;
     
     var
       { Error status variable }
       DosError : Integer = 0;
     
     procedure GetDate (var Year, Month, Day, DayOfWeek : Word);
       asmname '_p_getdate';
     procedure GetTime (var Hour, Minute, Second, Sec100 : Word);
       asmname '_p_gettime';
     procedure GetCBreak (var BreakOn : Boolean); asmname '_p_getcbreak';
     procedure SetCBreak (BreakOn : Boolean); asmname '_p_setcbreak';
     { GetVerify and SetVerify are dummies except for DJGPP (in the
       assumption that any real OS knows by itself when and how to verify
       its disks). }
     procedure GetVerify (var VerifyOn : Boolean);
       asmname '_p_getverify';
     procedure SetVerify (VerifyOn : Boolean); asmname '_p_setverify';
     function  DiskFree (Drive : Byte) : LongInt; asmname '_p_diskfree';
     function  DiskSize (Drive : Byte) : LongInt; asmname '_p_disksize';
     procedure GetFAttr (var F : GPC_AnyFile; var Attr : TDosAttr);
       asmname '_p_getfattr';
     procedure SetFAttr (var F : GPC_AnyFile; Attr : TDosAttr);
       asmname '_p_setfattr';
     procedure GetFTime (var F : GPC_AnyFile; var aTime : LongInt);
       asmname '_p_getftime';
     procedure SetFTime (var F : GPC_AnyFile; aTime : LongInt);
       asmname '_p_setftime';
     
     { FindFirst and FindNext are quite inefficient since they emulate
       all the brain-dead Dos stuff. If at all possible, the standard
       routines OpenDir, ReadDir and CloseDir (in the GPC unit) should be
       used instead. }
     procedure FindFirst (const Path : String; Attr : TDosAttr; var SR :
       SearchRec); asmname '_p_findfirst';
     procedure FindNext  (var SR : SearchRec); asmname '_p_findnext';
     
     procedure FindClose (var SR : SearchRec); asmname '_p_findclose';
     procedure UnpackTime (P : LongInt; var T : DateTime);
       asmname '_p_unpacktime';
     procedure PackTime (const T : DateTime; var P : LongInt);
       asmname '_p_packtime';
     function  FSearch (const aFileName, DirList : String) : TString;
       asmname '_p_fsearch';
     function  FExpand (const Path : String) : TString;
       asmname '_p_fexpand';
     procedure FSplit  (const Path : String; var Dir, Name, Ext :
       String); asmname '_p_fsplit';
     function  EnvCount : Integer;
     function  EnvStr (EnvIndex : Integer) : TString;
     function  GetEnv (const EnvVar : String) : TString;
       asmname '_p_getenv';
     procedure SwapVectors;
     { Exec executes a process via Execute, so RestoreTerminal is called
       with
       the argument True before and False after executing the process. }
     procedure Exec (const Path, Params : String);
     function  DosExitCode : Word;
     
     { Unportable Dos-only routines and declarations }
     
     {$ifdef __BP_UNPORTABLE_ROUTINES__}
     {$ifdef DJGPP}
     { These are unportable Dos-only declarations and routines, since
       interrupts are Dos and CPU specific (and have no place in a
       high-level program, anyway). }
     procedure Intr (IntNo : Byte; var Regs : Registers);
       asmname '_p_intr';
     procedure MsDos (var Regs : Registers); asmname '_p_msdos';
     {$endif}
     
     { Though probably all non-Dos system have versions numbers as well,
       returning them here would usually not do what is expected, e.g.
       testing if certain Dos features are present by comparing the
       version number. Therefore, this routine always returns 7 (i.e.,
       version 7.0) on non-Dos systems, in the assumption that any real
       OS has at least the features of Dos 7. }
     function  DosVersion : Word; asmname '_p_dosversion';
     
     { Changing the system date and time is a system administration task,
       not allowed to a normal process. On non-Dos systems, these
       routines emulate the changed date/time, but only for GetTime and
       GetDate (not the RTS date/time routines), and only for this
       process, not for child processes or even the parent process or
       system-wide. }
     procedure SetDate (Year, Month, Day : Word); asmname '_p_setdate';
     procedure SetTime (Hour, Minute, Second, Sec100 : Word);
       asmname '_p_settime';
     {$endif}

