LinCRT library.

In this document:

Introduction

Why LinCRT?

License

Working with LinCRT

Prior Notes

Initialization and Finishig Up

Windows

Input and Output

Interfacing with Mouse

Colors and Attributes

Repainting the Screen

Temporarily Quitting to the Shell

Interfacing with ncurses

 

Introduction

LinCRT library enables Kylix applications to perform extended text screen output (cursor positioning, color selection and so on). LinCRT library is designed so that many of its routines are analogous to those of Turbo Pascal CRT unit. At the same time LinCRT has some extended features (mouse support, extended character input/output).

This is the first public release of LinCRT and I have plans to extend its capabilities further, so it would be interesting to know if anybody finds the library useful and uses it in his applications.

If you have any comments and suggestions, feel free to write me at borovsky@pochtamt.ru

Why LinCRT?

There is a special CRT-output library in Linux called ncurses. LinCRT is actually based on this library and comes with the NCurses unit where ncurses library functions are declared in Pascal. While You can call ncurses functions directly with NCurses unit, I recommend You to use LinCRT instead. With LinCRT You can perform input and output in a standard Pascal way (I/O via standard ReadLn, Write and WriteLn routines is fully implemented). The other reason is that LinCRT interface can become a bases for a cross-platform console library, and in fact I'm planning to write a Delphi/Windows version of LinCRT.

License

LinCRT Copyright (c) 2002 Andrei Borovsky.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, distribute with modifications, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization.

 

Working with LinCRT

Prior Notes

The LinCRT library requires libncurses library which is provided by every Linux distribution. Make sure this library is installed in your system. Also make sure that there is a libncurses.so link to the actual library file in your /usr/lib/ directory. If there is no such link, make it with "ln -sf" command and run ldconfig.

Initialization and Finishig Up

The library is initialized by calling InitLinCRT procedure. Any other LinCRT routines may be called only after this call. If you have initialized the library with InitLinCRT, you have to call DoneLinCRT in the end of your program in order to clean up gracefully.

Windows

The basic concept of LinCRT output is a Window. The window is the rectangular area on screen where all the current output goes. The cursor position is always referenced relative to the upper left corner of the current window. Note that in LinCRT cursor coordinates start from 1. After initialization the library creates a window covering the entire terminal screen. With Window procedure it is possible to create windows of different sizes at different locations on the screen.

Input and Output

Under LinCRT the input and output can be performed with standard ReadLn, Write, and WriteLn procedures.

Note: due to some problems with underlying ncurses cursor-positioning handling it is recommended to call every ReadLn procedure in its own window.

Single characters can be put to screen with PutChar and PutCharXY procedures. When using the last two routines note that they don't change the current cursor position. The are also two functions: GetKey and ReadKey that handle input on per-character basis. These functions do not echo incoming characters on the screen. The ReadKey function is introduced for CRT compatibility. The GetKey function is an extended variant of ReadKey. This function allows for mouse support.

The GetKey and ReadKey functions are blocking. In order to do a non-blocking input with these functions use the non-blocking KeyPressed function as shown below:

while ... do // some control loop

begin

...

if KeyPressed then Key := GetKey;

...

end;

In LinCRT ReadKey acts just like it did in old CRT library. When some non-character key (like F1 or cursor arrow) is pressed, ReadKey should be called twice. The first call to ReadKey returns 0. The second ReadKey call returns the special code for the key pressed. The codes returned by ReadKey are the same as those returned with CRT library and they don't coinside with the codes returned by GetKey function. Unlike the ReadKey function, the GetKey function always returns meaningful codes at the single call. This will be either a character code or a special pseudo-character code defined in LinCRT unit.

Interfacing with Mouse

X-Windows terminals make it possible for the application to process mouse messages. In LinCRT mouse support is turned on by calling InitMouse procedure. After the mouse support is turned on, the KeyPressed function will react on a mouse button being pressed and the GetKey function will return special pseudo-character code indicating what button has been pressed. The mouse position at the moment of the last button pressure can be obtained by the call to WhereMouseXY function.

The mouse support can be turned off by the call to KillMouse procedure.

Colors and Attributes

Text and background colors may be set by TextColor, TextBackground and SetColors procedures using the color constants defined in LinCRT unit. Only the first 7 colors may be used as the background colors. The text colors may be used in combination with Blink value. In this case the following text output will be blinking. Calling a color-setting routine without Blink constant removes the blinking effect for the subsequent output.

The current attributes (text and background colors, blinking mode) are stored in TextAttr variable - just like in CRT unit - in the following format:

B

b

b

b

f

f

f

f

7

6

5

4

3

2

1

0

where B is blinking mode bit, b - background color bits, f - text color bits.

LinCRT allows you to get the attributes at the particular screen position by means of GetColorXY function. This function returns the byte, containing the attribute information for the specified screen cell in the format analogous to that of TextAttr variable.

LinCRT allows also to set some additional text attributes: text underlining and text inversion. Setting, unsetting, controlling these parameters is done via Inverse and Underline boolean variables. You can get the values of this additional parameters for some particular cell with GetAddAttrXY function.

Repainting the Screen

When a console application is running in the X-Windows terminal window it must be aware that the screen dimensions can change at any time. This happens when the user resizes the window or changes the terminal font.

If your application is intended to be used under X-Windows terminal it will have to handle screen resizing and repainting correctly. LinCRT library declares OnTermResize variable of type TOnTermResize. The definition of this type looks as follows:

TOnTermResizeProc = procedure(DoingInput : Boolean);

If you assign a procedure to OnTermResize, this procedure will be called each time the screen dimension change. DoingInput parameter is True if the screen coordinates have changed when ReadLn procedure was being executed. In this case you can change the cursor position and the ReadLn input will continue at the new location (this works only if BeakOnResize variable is set to False).

Note that when screen is resized the current LinCRT window openede with Window procedure will be closed. The screen dimensions are stored in SrcLines and ScrCols variables. When OnTermResize procedure is called these variables already store new values.

By default ReadLn procedure is not interrupted when the screen is resized. You can change this behavior by setting BreakOnResize variable to True. In this case the ReadLn procedure will return each time the screen dimensions change. The variables passed to ReadLn will contain the user's input. If the input was interrupted by the screen resize the Broken variable is set to True when ReadLn returns. Otherwise the Broken is set to False. You can handle input interrupts in the following way:

BreakOnResize := True;

...

ReadLn(SomeValue);

if Broken then ... // screen is resized

else ... // user has pressed [Enter].

Temporarily Quitting to the Shell

LinCRT allows you to start the copy of the shell on the terminal where the program is run. The shell copy is started by ShellOut procedure. The single parameter of this procedure is the command string that starts the shell or other process. Calling ShellOut suspends the calling process until the user exits the shell.

Interfacing with ncurses.

When using LinCRT you can call underlying ncurses routines directly (using the NCurses module). Most ncurses routines require pointer to the window structure to operate on. For this LinCRT provides two variables: CurWnd and StdScr. The first variable points to the structure corresponding to the current window, the second - to the whole screen.

While ncurses cursor coordinates are referenced starting from 0, LinCRT coordinates (like CRT's) start from 1. You should keep this in mind when translating from LinCRT coordinates to ncurses coordinates and vice versa.

LinCRT input functions work correctly in the keypad(True) mode. If you change this mode when working with ncurses, don't forget to restore it when turning back to LinCRT routines.