                        GT Slang driver


A GT Slang driver for Harbour (gtsln) is based on a S-Lang library written
by John E. Davis. It was developed using Slang version 1.41, although prior
versions of Slang up to 1.22 should also work, but they are not recommended
because of some bugs they have.

The main OS it is developed to be used on is Linux. Slang was ported to
other OSes so it should be possible to use it on other systems too. I've
also successfully compiled and tested gtsln under MS-DOS but I don't think it
makes any sense to use it on that system instead of gtdos, due to its
limitations and incompatibilities with CA-Cl*pper (see below), so I removed
MS-DOS support.

A gt Slang driver is a second driver which can be used on Unix based OSes.
The first one is a gt driver based on a curses library (gtcrs). Due to the
fact that curses is a standard library on Unix like systems, gtcrs should
be considered as a primary gt driver for such OSes.



Compiling a gt slang driver ...
--------------------------------


The driver should be automatically compiled when you build Harbour from
sources, regardless of what gt driver you've chosen by setting HB_GT_LIB.
Successful compilation requires Slang library and Slang header files
properly installed on your system. The driver expects Slang header files
to be placed in <system_default_inc_dir>/slang/ directory on Linux based
systems ( this usually means /usr/include/slang on most of them ) and
<system_default_inc_dir> on other systems (which is usually /usr/include).

To build programs (by using a bld.sh script from Harbour sources), which
will use a gtsln, you need to :
    - have a Slang library and header files properly installed
    - set an environment variable HB_GT_LIB to gtsln
    - modify bld.sh by adding -lslang to a link command

Generally you always need to add -lgtsln -lslang to your link libraries to
build programs which are supposed to use a gt slang driver.



Internationalization
----------------------


I made an attempt to support national characters handling, but I am not
sure if it is done in a proper way. The implementation supports only one
byte encoding, thus Korean and other two bytes encodings are not allowed.
It assumes national characters are placed in an upper 128 bytes of ASCII
table from a normal character set. "Normal" means not "alternate character
set" here, because "alternate character set" is generally used to display
graphics characters. It also assumes national characters can be entered
for example by pressing an <AltR> key and a particular key on a keyboard
to get a desired national character. If this is impossible on some terminals
due to their lack of possibilities, an alternate method which uses Dead
keys, is implemented. To be able to see and to enter national characters
one should :

 - have a proper font table loaded
 - optionally have a software installed to allow enter national characters
   in whatever way they should be entered
 - have an environment variable HRBNATIONCHARS properly set (see below)
 - optionally have a HRBNATIONDEADKEY defined (see below)

An environment variable HRBNATIONCHARS should contain a list of character
pairs. A first character from each pair should be a character from a lower
128 bytes of ASCII table, which should be pressed after a Dead Key was
pressed, to get a desired national character. The second character is a
national character itself. Those pairs should be defined even if a Dead
key is not used (because a terminal supports other method of entering
national characters - for example <AltR + letter>).

If a terminal does not support entering national characters by using an
ALT key (or the other similar) an environment variable HRBNATIONDEADKEY
can be defined. It should contain a character which should be pressed
*before* a particular key on a keyboard is pressed to get a desired
national character.

The reason I am using HRBNATIONCHARS envvar is simple. I want to give a
better graphics chars support when the same code is occupied by a nation
char and by a graphics char. Because on terminals there are usually two
glyph's character sets (normal and alternate) knowing nation's characters
codes, I can switch to normal character set when a nation character code
is encountered, while still being in an alternate character set for other
characters. This way I can draw boxes properly using box drawing commands
even though characters for box drawing occupy the same code a nation chars
occupy. So commands like :

            @ Y1, X1 TO Y2, X2 [ DOUBLE ]
            @ Y1, X1, Y2, X2 BOX "<BoxString>"

should write boxes well. However commands like :

            @ Y, X SAY Chr( <OneOfBoxDrawingChar> )

will draw a nation char when it occupies the same code as
<OneOfBoxDrawingChar> occupies. I don't know a better solution in this
case. Any ideas are welcome.
This implementation works better than it would ever work in MS-DOS where
there is no way to do such tricks (because there is only one glyph's
character set without VGA tricks).

Using environment variables gives a configuration flexibility to Harbour
programs for different users and different code pages. To change a code
page one should only change HRBNATIONCHARS var (if a Dead key is used)
and this can be done from a script which runs a Harbour program.

Let's see an example.

Suppose one national language has three national characters : 'ĄĆĘ' which
correspond to 'ACE' in a lower 128 bytes ASCII table. 'Corresponding' means
that to get a 'Ą' nation char one has to press a special keyboard modifier
(like ALT+R for example) plus an 'A' char.

HRBNATIONCHARS should be defined as :

        HRBNATIONCHARS=AĄCĆEĘ

   where AĄ is a first pair, CĆ is a second pair and so on

Suppose also we are working on a terminal which does not allow to enter
national characters by pressing <AltR+A>, <AltR+C>, <AltR+E>. Because we
like a character '`' (\140 in octal), we arbitrary choose it as a Dead key.

So we define HRBNATIONDEADKEY as :

        HRBNATIONDEADKEY=\`

or in other way :

        HRBNATIONDEADKEY=`echo -ne '\140`'

Now we can enter Ą by pressing ` and then A, Ć by pressing ` and then C,
and so on. To get '`' character we need to double press `.



Limitations, incompatibilities with CA-Cl*pper, errors ...
--------------------------------------------------------


The driver is rather limited in comparison to other Harbour gt drivers and
has many incompatibilities with CA-Cl*pper. Some of those limitations and
incompatibilities are caused by an Unix behavior, others are caused by a Slang
implementation. There are also some caused by a gt layer design. Not to
mention that there are probably some caused by my lack of knowledge.

Here is a (probably not complete) list of them :

    - a driver allows only 128 combinations of FgBg colors. It means you can
      use 16 colors for Fg, and only 8 colors for Bg.

    - you cannot get intensity/blinking background mode working (this is in
      fact the previous problem, just worded differently)

    - you cannot display characters with values below 32 (control characters).
      It is a very important limitation because you cannot use many useful
      chars which you used under CA-Cl*pper. This is an OS limitation which
      Slang also inherits

    - displaying chars above 128 widely depends on terminal possibilities.
      Because of this on xterm I set all frame chars to a single frame
      (this means - double and mixed frames are shown as a single frame).
      You should not expect to see chars above 128 shown properly in all
      cases.

    - a screen is automatically cleared on program's startup (you cannot inherit
      it from a system) and a cursor is set at 0,0

    - when you run external programs a screen is restored after execution so
      there is no possibility to interact with screen handling between two
      programs

    - you cannot expect cursor hiding and cursor style changing to work at
      all. Although on a text-mode Linux console it works, this is a Linux
      text-mode hack only and it is hardcoded. For example on xterm only
      cursor hiding works well.

    - it is not guaranteed that programs which use DispBegin() and DispEnd()
      will work well in all cases, although generally it should work

    - a screen size change does not work at all. This is a big problem on
      an xterm where you can change a window's size at your request.  Doing
      this confuses a Harbour program

    - CA-Cl*pper programs which utilized PC hardware specifications about screen
      construction (an array of char+attr)  (for example to make quick shadow
      on a screen) cannot run properly. There is no hardware emulation at all

    - Tone() support currently works for Linux console only.

    - keyboard handling is VERY LIMITED. Generally you should not expect
      ALT+key, CTRL+F<n> and CTRL+<specialkeys> combinations to work at all
      although they work on a text-mode Linux console. This is a very big
      problem and at least any solution should be developed to emulate this.
      One attempt is a Dead key workaround I've implemented for national
      characters and a Meta key to simulate Alt key. By default as a Meta
      key I've chosen ESC key pressed once (like in most Linux programs).

    - abort key is CTRL+\ not CTRL+BREAK on Unixes

    - to get an ESC key you have to press ESC twice. This is an issue
      related to OS behavior where ESC begins a control sequence

    - currently there is no mouse support. This is a TODO item

    - Out<XXX>() functions do not work well. This is caused by a design of
      a gt layer where writing directly to STDOUT is done outside Slang,
      so Slang cannot maintain screen changes properly.

    - redirecting Out<XXX>() to a file results in writing control chars
      which were supposed to initialize a terminal, to that file

    - monochrome displaying support is currently broken



Terminfo database ...
-----------------------


Slang gt driver is based on a terminfo database so it is very important to
have it properly set. Most problems are related to a broken terminfo file.
I don't have general advice about that. You are supposed to help yourself.
The only thing you should know is that you must not have sequences for <F11>
and <F12> function keys set in a terminfo file if you want to use <Shift+Fn>
and <Ctrl+Fn> keys (of course they all should be defined there).



Why use gt slang driver ...
-----------------------------


Well, personally I find only two reasons. When CA-Cl*pper compatibility and
current limitations are not a problem, gtsln is a little bit faster than
gtcrs and my experiences show that sometimes it works a little bit better
than gtcrs on real terminals (tested on wy60 where gtcrs did not handle
the keyboard well).



TODO
------

   - keyboard emulation on terminals with lack of possibilities
   - support for mouse on Linux text console and on xterm
   - fix a problem with redirecting output to a file or a pipe
   - find a way to inherit screen from a system at startup
     (is it possible at all ?)
   - sound support on Linux using native sound system (Alsa ?)
   - support for sound on other systems than Linux
   - fix working on monochrome terminals
   - add a PC video card hardware emulation


   Marek Paliwoda
<paliwoda@inetia.pl>


PS.
I want to apologize for any English errors
and any technical errors in this text.
