GT API functions
================
By Bil Simser (1999-05-14)

Using the gt API requires two steps.
The gt API interface is kept in gtapi.c. This houses the gt API and
does not have any platform or compiler specific information. This file
should (read:will) never change except to add new _gt functions. This
file will be used by Harbour or Harbour functions and must be linked
into the RTL.

The second step requires you to link in your platform specific
implementation of the _gt functions. These are functions named with
gtxxxxxx convention and are called by the _gt functions in gtapi.c.
I've provided the following files to implement the console functions:

gtdos.c - MS-DOS implementation
gtwin.c - Windows implementation
gtos2.c - OS/2 implementation
gtxxx.c - Generic template for implementation

If you wish to port the gt functions to another platform, just take the
gtxxx.c and populate it with calls to your OSes functions. Call the file
something appropriate (gtmac.c, gtnext.c or whatever) and add it to
that platforms Makefile.

The API supports a dozen or so compilers on three platforms. You only
have to change the gtxxx.c files to implement your platform.

The API needs to be initialized for Windows to setup the Input and Output
handles. These are done in _gtInit() and should always be called. Not sure
how this will be implemented (if at all) into Harbour but it needs to happen
or else you won't see any output under Windows.

There's a test section at the end of gtapi.c. I didn't want to keep
rebuilding

Harbour to build a PRG test and PRGs shouldn't call the _gt functions
directly anyway. Just compile gtapi.c alone with a #define of TEST to see
the output (or build a PRG test if you want).

You must include gtapi.c and one of the platform implementation files
to compile successfully!

There are exceptions for various compilers in the platform implementation
files so if you're using a compiler that doesn't support certain routines
or syntax just stick in your changes and surround it with an
`#if defined( __XXX__ )` call.

This is a complete set of gt functions as defined by Clipper. That is
there are no new _gt functions added. But this is not a complete
implementation. I do not know what _gtBegin() or _gtEnd() will do for
instance. Yes, they buffer the display but what does that really mean
under the covers? Perhaps someone needs to implement a screen buffer
to write to in order to achieve this but the issue that immediately comes
to mind is how to initialize the size of this buffer?

The files are attached but I will NOT be checking them into cvs for the
following reasons:

1. There is already a gtapi.c file and under no circumstances will I ever
overwrite someones code. If the author wants to remove his file and check
this in then be my guest.

2. This is my vision of how "I" think the gt API should be implemented.
Perhaps it isn't Antonio's or anyone else's so review it and if you feel
that it deserves being put into Harbour I'll leave that up to you.

TODO:
The following functions are not implemented in gtapi.c:
_gtPostExt()
_gtPreExt()
_gtScroll()
_gtSetBlink()
_gtSetMode()

The following functions don't work in gtapi.c:
_gtSave()
_gtRestore()

Two Harbour functions are included in the gtapi.c file,
Row() and Col() to get started.

You also may notice that I didn't include any NanFor document headers or
even any cvs macros. The jury is still out on that so I'll leave that to the
reader.

I release this to anyone who wants it. If you feel you don't like the
implementation and want to pursue a different approach, please do.
By not checking this in I'm not forcing anyone to use it.
If however you do feel it's a good start
(or a better start than what we have)
the please check it in and start writing those other terminal functions
(DEVPOS, etc.)

Best regards,
Bil.


How to get rid of unwanted console in Windows GUI applications
==============================================================
By Przemyslaw Czerpak (druzus/at/priv.onet.pl)

Do not use GTWIN :-)
GTWIN is a driver for users who wants to write CUI applications and
should give them all possible features. GUI libraries do not have to
use GT drivers if they don't need any GT functionality, or if they
don't want to give users support for standard Clipper/Harbour functions
which operate on GT resources.

Harbour application can work without any GT driver. In such case all
functions which operates on GT resources are redirected to meta GT
driver (GTNUL) which is part of RTL library. This driver makes all
operations on memory buffer and only OutStd()/OutErr() output is sent
outside. All GT drivers inherits from GTNUL or from other GTs but in
the inheritance chain the first GT driver is always GTNUL.

Because there is no hard coded bindings between core code and other GT
drivers, then by default only GTNUL will be linked. So if you will want
to use some real GT you will have to add to your code:

    REQUEST HB_GT_<name>

Setting the default GT driver is done exactly the same as setting the
default RDD. In RDD it request DBFNTX by default. It is done inside a
module with RDDSYS() symbol, and core code contains:

    REQUEST RDDSYS

Something like that is also done by Clipper. If you add to your code
RDDSYS symbol, then the default RDD will not be linked because your
RDDSYS will overload the default one (of course if it will be linked
before the one in core code). So it's enough to write something like:

    ANNOUNCE RDDSYS
or:
    PROCEDURE RDDSYS(); RETURN

Both gives the same effect, and default RDD (DBFNTX) will not be linked.
Exactly the same I've done in GT subsystem. hb_GTSYS() makes exactly
the same job as RDDSYS() but for GT. This symbol is requested by core
code and in the module where it is defined it request default build GT
driver or if it's not set then default GT driver for given platform.
For Windows it looks like:

    ANNOUNCE HB_GTSYS
    REQUEST HB_GT_WIN

This causes that normal console applications do not have to explicitly
request GT driver and the one set in the module with HB_GTSYS is always
linked. If you do not want to link the GT driver then you have to make
the same as for RDD and add to your code:

    ANNOUNCE HB_GTSYS
or:
    PROCEDURE hb_GTSYS(); RETURN

In such case your final application will not have any GT driver. If you
want to use GTNUL as base, you should add:

    REQUEST HB_GT_NUL

Though IMHO this request should be part of GUI library core code. You
can link with your application more then one GT driver. It's enough
that you add more lines with:

    REQUEST HB_GT_<name>

For example, compile this code:

    /*** t.prg ***/
    REQUEST HB_GT_WIN
    REQUEST HB_GT_WVT

    PROCEDURE Main()

       ? hb_gtVersion(), hb_gtVersion( 1 )
       Tone( 200, 3 )
       Tone( 300, 3 )
       Tone( 500, 3 )
       Inkey( 0 )

       RETURN

and link it as Windows GUI application. Then simply execute:

    t --hb:gtwin
and:
    t --hb:gtwvt

Most of Windows linkers execute startup initialization code in the
order of linked modules, so the first linked GT driver will be the
default one. But you can control it also from your application, by
requesting HB_GT_<name>_DEFAULT symbol (I do not like this name because
it cannot be used with 10 character symbols so I'm ready for any other
positions). For example, if you add to your code:

   REQUEST HB_GT_NUL_DEFAULT

Then GTNUL will be the default GT driver, and even if you would not
disable GTWIN and link it with your application, GTWIN will not be
activated but GTNUL.

It could be intentional, because if your application is linked with more
GTs, then you can also set the default one when you start your
application using --hb:gt<name> switch, or HB_GT environment variable.
So you can create GUI application which will set the default GT driver
to NUL and will not activate GTWIN, and when you'll want to enable debug
messages, you simply run:

    myprog --hb:gtwin

and debug messages will use the GTWIN console window. You can think of
other situations when it could be useful to have full functional GT
driver in GUI application. You can even create mixed GUI/CUI code in one
program.

And finally, the Tone() function problem.
Low-level Tone() code is part of GT driver. In the past, GUI libraries in
Windows were linked the whole GTWIN driver and only Tone() were used. It
was possible because someone blocked GTWIN to work with application
linked as Windows GUI programs. Now, GTWIN can be used with any
applications, and I do not want reduce its functionality. So GUI
libraries which needs Tone() should have their own GT driver which will
support it. Now, such GT driver can also give much more features for
final users, because it allow to integrate GUI library with standard
Clipper screen functions.

How to create such base GUI GT driver?
See as example GTGUI in src/rtl/gtgui/gtgui.c
It supports only Tone() and CLIPBOARD operations.
GUI libraries can use it or create other GT driver inheriting from
this one.


gtnul  - base GT driver from which each other inherits.
         it gives screen buffer functionality but does not
         produce any screen output from disp*() commands
         Only OutStd()/OutErr() are supported.
         It's present on all platforms and i always linked.

gtcgi  - very simple GT driver which does not make any output
         formatting and simply send it as to STDOUT.
         Supported by all platforms.

gtstd  - it uses STDOUT output but tries to support full screen output but
         without color support and cursor shape. It format text to number
         of row and columns if is able to detect these values on given
         platform.
         Supported by all platforms.

gtpca  - It's PC-ANSI terminal GT - it works in similar way to ANSI GT
         driver in Clipper though keyboard input is not fully supported.
         Now GTTRM can make all GTPCA job and much more.
         Supported by all platforms.

gtdos  - GT driver for MS-DOS - it uses BIOS and direct hardware screen output
         so it's very similar to Clipper one - in practice due to the same
         environment you will noticed that all small details of Clipper
         GT drivers are replicated here. You can think about it like 100%
         Clipper compatible.
         Supported only by MS-DOS builds.

gtos2  - GT driver for OS/2 - It's similar to GTWIN but for another OS.
         Supported only by OS/2 builds.

gtwin  - GT driver for MS-Windows console window.
         Supported only by Windows builds.

gtcrs  - GT driver for platforms which supports curses or compatible
         (ncurses) library - in practice POSIX systems.
         Supported by POSIX systems (mostly different *nixes)

gtsln  - GT driver for platforms which supports slang library.
         It's like GTCRS but instead of CURSES it uses SLANG.
         Supported by POSIX systems (mostly different *nixes).
         It supports Unicode input/output if compiled with slang
         version which also supports it.

gttrm  - it's like GTCRS and GTSLN but it does not use any external
         terminal library like SLANG or CURSES and it does not use
         any external database to extract terminal capabilities so
         it can be compiled on any POSIX system - I'll add support
         also for MS-DOS/Windows in the future. It should automatically
         detect UTF-8 terminal mode and switch internally to Unicode
         mode if necessary. In theory is less functional then GTCRS
         and GTSLN because I hard coded escape sequences only for few
         terminals but because I added support also for some non
         standard terminal extensions and I'm using very limited set
         of output sequences then it usually works better then GTCRS
         and GTSLN.
         Supported by POSIX systems (mostly different *nixes)

gtwvt  - GT driver for MS-Windows. It creates its own GUI window
         instead of using MS-console window. It allows to change
         font, window size, etc.
         Supported only by Windows builds.
         is a pure console implementation of traditional Clipper terminal
         taking Windows API as its base console IO protocols. Its OI are
         rendered in a Windows window and hence all of MSDN is available
         for use with GTWVT.
 To let the memory refreshed, I must remind
         everybody that it is a superb work of Peter Rees contributed
         to xHarbour on 2003-12-22.
gtwvg  - GUI emulation of GTWVT. It implements itself on top of GTWVT.
         GTWVG ( WVTGUI in xHarbour ) offers functions and classes to
         present a console application look like a windows one.
         It renders GUI elements on top of Clipper elements
         ( GETS, BROWSERS, BOXES, LINES ) which makes them
         feel like a Windows element. GTWVG can be used with existing
         code just adding some more code but without sacrificing or
         modifying old one.
         Also all IO commands can be rendered on top of the GUI elements
gtxwc  - GT driver for X-Window. It's like GTWVT but for nixes.
         Additionally it has set of predefined vector characters
         (box and arrow drawing characters) which can be used
         instead of the one defined in font. It means that you
         will have all boxes and arrows you know from MS-DOS and CP437
         even if you chose font which does not have them. Additionally
         it support some simple graphic output. See tests/gfx.prg
         for simple program which demonstrates it.
         Supported by POSIX systems (mostly different *nixes)

gtalleg- GT driver which uses Allegro library for input/output.
         It's also GUI driver which support HB_GFX*() drawing.
         Multi platform, works on all platforms for which allegro
         library has been ported: MS-Windows, MS-DOS, VESA, X11, FB, SDL, ...

gtgui  - pseudo GT driver which adds to GTNUL Clipboard and Tone()
         functionality. If you are using some MS-Windows GUI library
         and you still want to use Tone() function or HB_GTI_CLIPBOARD
         actions then link this GT driver with your application.
         If you do not want to use Tone() or HB_GTI_CLIPBOARD then
         do not link it - it will be only waste of memory.

gtctw  - GT driver which adds CT3 Window functionality to any other
         GT driver from which it inherits. It's activated automatically
         when you execute first W*() function.
         In similar way in Harbour it's possible to add support for
         GTWVW/GTWVG inheriting from GTWVT.

Some of the GT drivers support additional functionality with hb_gtInfo()
interface.
See include/hbgtinfo.ch for different actions.

Best regards,
Przemek
