ChangeLog 2001-03-27 20:05 UTC+0100

This commit is contained in:
Ryszard Glab
2001-03-27 18:10:32 +00:00
parent 4b9b3376ab
commit e5ff2cd515
5 changed files with 1091 additions and 533 deletions

View File

@@ -1,3 +1,24 @@
2001-03-27 20:05 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
Changes from Marek Paliwoda. Thanks Marek :)
*doc/en/gtslang.txt
*source/rtl/gtsln/gtsln.c
*source/rtl/gtsln/kbsln.c
*source/rtl/gtsln/keytrans.c
- added support for displaying and entering national characters (see
gtslang.txt for details)
- improved keyboard support for linux text console. Almost all
ALT/CTRL+
SpecialKeys should work well. Note that You have to work using true
/dev/tty[1-12] device. This means You can't benefit from it when You
run Harbour programs from within Midnight Commander for example,
because
MC uses pseudoterminals.
- prepared for other Unix text consoles (SCO) (not tested)
- removed support for DOS. It was totally not needed due its
limitations
2001-03-27 05:18 GMT-3 Horacio Roldan <horacioroldan@usa.net>
* harbour/source/rdd/dbcmd.c
* fixed unallocated memory block in dbcreate

View File

@@ -2,87 +2,182 @@
* $Id$
*/
Marek Paliwoda
<paliwoda@inetia.pl>
Gt Slang driver
Gt slang driver
A gt slang driver for Harbour (gtsln) is based on a S-Lang library written
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.38 should also work. It was reported that even
Slang 1.22 was succesfully used but I've not tested it.
versions of Slang up to 1.22 should also work, but they are not recomended
because of some bugs they have.
The main OS it is developed to be used on is Linux. Although Slang was
ported to other OSes, my tests on SCO OpenServer 5.0.2 show that a library
does not work perfectly on such systems. I've also successfully compiled and
testd gtsln under 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
Clipper (see below).
system instead of gtdos, due to its limitations and incompatibilities with
Clipper (see below), so I removed DOS support.
A gt slang driver is a second driver which can be used on Linux based OSes.
A gt Slang driver is a second driver which can be used on Linux 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
fact that curses is a standard library on Unix like systems, gtcrs should
be considerd as a primary gt driver for such OSes.
Compiling a gt slang driver ...
The driver should be automaticly compiled when you build Harbour from
1. Compiling a gt slang driver ...
The driver should be automaticly compiled when you build Harbour from
source, regardless of what gt driver you've chosen by setting HB_GT_LIB.
Succesfull compilation requires Slang library and Slang header files
properly installed on your system.
Succesfull 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. This usualy
means /usr/include/slang on most systems.
To build programs (by using a bld.sh script from Harbour sources), which
To build programs (by using a bld.sh script from Harbour sources), which
will use a gtsln, you need to :
- have a Slang library properly installed
- set an environment variable HB_GT_LIB set to gtsln
- 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.
Limitations, incomatibilities with Clipper, errors ...
The driver is rather limited in comparison to other Harbour gt drivers and has
many incompatibilities with Clipper. Some of those limitations and incompati-
bilities are caused by an Unix behavior, others are caused by a Slang imple-
mentation. There are also some caused by a gt layer design. Not to mention
that there are probably some caused by my lack of knowledge.
2. 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 posibilities, 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
- optionaly 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)
- optionaly have a HRBNATIONDEADKEY defined (see below)
An environment variable HRBNATIONCHARS should contain a list of character
pairs. A first character from each pair sholud 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 ocupied 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 DOS where
there is no way to do such tricks (because there is only one glyph's
character set).
Using environment variables gives a configuration fexibility 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 corespond to ACE in a lower 128 bytes ASCII table.
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 `.
3. Limitations, incomatibilities with Clipper, errors ...
The driver is rather limited in comparison to other Harbour gt drivers and
has many incompatibilities with Clipper. Some of those limitations and in-
compatibilities 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 126 combinations of FgBg colors. It means you can
use 16 colors for Fg, 8 colors for Bg. 16*8 gives 128 but last two (126
use 16 colors for Fg, 8 colors for Bg. 16*8 gives 128 but last two (126
and 127) are reserved by Slang
- you can't get intensity/blinking background mode working (this is in
fact the previous problem, just worded differently)
- you can't display characters with values below 32 (control characters).
It is a very important limitation because you can't use many usefull
chars which you used under Clipper. This is an OS limitation which
It is a very important limitation because you can't use many usefull
chars which you used under Clipper. This is an OS limitation which
Slang also inherits
- displaying chars above 128 widely depends on terminal posibilities.
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.
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 automaticly cleared on program's startup (you can't inherit
it from system) and a cursor is set at 0,0
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
there is no possibility to interact with screen handling between two
programs
- you can't expect cursor hiding and cursor style changing to work at
all. Although on a textmode Linux console it works, this is a Linux
textmode hack only and it is hardcoded. For example on xterm only cur-
sor hiding works well.
textmode 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
will work well in all cases, although generally it should work
- a screen size change does not work at all. There is a big problem on
an xterm where you can change a window's size at your request. Doing
@@ -90,30 +185,35 @@ Here is a (probably not complete) list of them :
- Clipper programs which utilized PC hardware specifications about screen
construction (an array of char+attr) (for example to make quick shadow
on a screen) will not work, although this can be easily emulated if
required
on a screen) can't run properly. There is no hardware emulation at all
- there is currently no support for Tone() function. This is a TODO item
- keyboard handling is VERY 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 textmode Linux console. This is a VERY BIG
PROBLEM and at least any solution should be developed to emulate this
ALT+key, CTRL+F<n> and CTRL+<specialkeys> combinations to work at all
although they work on a textmode 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
- abort key is CTRL+C not ALT+C on Unixes, although it still is ALT+C
on Linux text console
- 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
- abort key is CTRL+C not ALT+C on Linux
- 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
- OutStd() does not work well. This is caused by a design of a gt layer
where writing directly to stdout is done outside Slang, so Slang can't
maintain screen changes properly. Also redirecting OutStd() to a file
results in writing control chars which were supposed to initialize a
terminal, to that file
- 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 can't maintain screen changes properly.
Also 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
4. Terminfo database ...
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.
@@ -122,15 +222,31 @@ 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 SHFT+F<n>
and CTRL+F<n> keys (of course they all should be defined there).
Why use gt slang driver ...
Well, personaly I find only two reasons. When Clipper compatibility and
5. Why use gt slang driver ...
Well, personaly I find only two reasons. When Clipper 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).
than gtcrs on real terminals (tested on wy60 where gtcrs did not handle
the keyboard well).
Marek Paliwoda
PS. I want to appologize for any english errors and any technical errors in
this text.
6. TODO
- keyboard emulation on terminals with lack of posibilities
- 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
- fix working on monochorme terminals
- sound support on Linux
Marek Paliwoda
<paliwoda@inetia.pl>
PS.
I want to appologize for any english errors
and any technical errors in this text.

View File

@@ -35,12 +35,14 @@
/* NOTE: User programs should never call this layer directly! */
/* *********************************************************************** */
#ifdef __linux__
#include <slang/slang.h>
#else
#include <slang.h>
#endif
/* missing defines in previous versions of Slang - this was not TESTED !! */
/* missing defines in previous versions of Slang - this can not work ! */
#if SLANG_VERSION < 10400
typedef unsigned short SLsmg_Char_Type;
#define SLSMG_EXTRACT_CHAR( x ) ( ( x ) & 0xFF )
@@ -56,6 +58,8 @@
#include "hbapigt.h"
#include "inkey.ch"
/* *********************************************************************** */
/* if we can not manipulate cursor state */
#define SC_UNAVAIL -1
@@ -64,23 +68,32 @@
*/
#define SLANG_RESERVED_COLORS 2
#ifdef IBMPC_SYSTEM
int SLtt_Has_Alt_Charset = 1;
char * SLtt_Graphics_Char_Pairs = "";
#endif
/* to convert DeadKey+letter to national character */
extern unsigned char s_convKDeadKeys[];
extern int hb_gt_Init_Terminal( int phase );
/* to convert characters desplayed */
static void hb_gt_build_conv_tabs();
static USHORT s_uiDispCount;
/* the name of an environmet variable containig a definition of Nation chars.*/
/* A definition is a list of pairs of chars. The first char in each pair is */
/* an ASCII key, which should be pressed *after* a "DeadKey" was pressed to */
/* get the nation char, a second in that pair is a corresponding nation char */
unsigned char *hb_NationCharsEnvName = "HRBNATIONCHARS";
/* *********************************************************************** */
static USHORT s_uiDispCount = 0;
static SHORT s_sCursorStyle = SC_NORMAL;
static BOOL s_linuxConsole = FALSE;
static BOOL s_underXTerm = FALSE;
/* indicate if we are currently running a command from system */
static BOOL s_bSuspended = FALSE;
/* to convert high characters (mostly graphics and control chars) */
static unsigned char s_convHighChars[ 256 ];
/* to convert high characters (mostly graphics, nation and control chars) */
static SLsmg_Char_Type s_convHighChars[ 256 ];
/* bit indication if char is a nation char - assums char is 8-bit */
static unsigned char s_IsNationChar[ 128 / 8 ];
/* to convert colors to Clipper mode */
static char * s_colorNames[] =
{
@@ -102,15 +115,20 @@ static char * s_colorNames[] =
"white"
};
/* a box drawing hack when nation chars are used */
static BOOL s_bUse_Alt_Char_Hack = FALSE;
/* *********************************************************************** */
volatile BOOL hb_gt_sln_bScreen_Size_Changed = FALSE;
#ifndef IBMPC_SYSTEM
/* window's resize handler */
static void sigwinch_handler( int sig )
{
hb_gt_sln_bScreen_Size_Changed = TRUE;
SLsignal( SIGWINCH, sigwinch_handler );
}
#endif
/* *********************************************************************** */
/* I think this function should not be void. It should be BOOL */
void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr )
@@ -127,17 +145,14 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr )
if( SLkp_init() != -1 )
{
/* initialize a terminal stuff and a Slang
keyboard subsystem for the first time
*/
keyboard subsystem for the first time */
if( hb_gt_Init_Terminal( 0 ) )
{
/* initialize a screen handling subsytem */
if( SLsmg_init_smg() != -1 )
{
#ifndef IBMPC_SYSTEM
/* install window resize handler */
SLsignal( SIGWINCH, sigwinch_handler );
#endif
/* do not indicate USER_BREAK in SLang_Error - ??? */
SLang_Ignore_User_Abort = 1;
@@ -148,7 +163,7 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr )
/* NOTE: this is incompatible with CLIPPER
but under Unix we should assume cursor is
visible on startup because we cannot figure
out a current cursor state
out a current cursor state
*/
/* turn on a cursor visibility */
if( SLtt_set_cursor_visibility( 1 ) == -1 )
@@ -162,26 +177,24 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr )
/* NOTE: this driver is implemented in a way that it is
imposible to get intensity/blinking background mode
under Slang, due to a way Slang is written. This is
incompatible with Clipper.
*/
#ifndef IBMPC_SYSTEM
incompatible with Clipper. */
SLtt_Blink_Mode = 0;
SLtt_Use_Blink_For_ACS = 0;
#endif
SLsmg_Display_Eight_Bit = 160;
/* initialize conversion tables */
hb_gt_build_conv_tabs();
/* ensure we are in a normal chars set */
SLtt_set_alt_char_set( 0 );
#if SLANG_VERSION < 10401
/* NOTE: due to a work of a Slang library which does not
prepare its internal screen buffer properly, a screen
must be cleared before normal work. This is not
compatible with Clipper
*/
#ifndef IBMPC_SYSTEM
/* ensure we are in a normal chars set */
SLtt_set_alt_char_set( 0 );
#endif
compatible with Clipper */
SLsmg_cls();
#endif
/* SLsmg_set_color( 7 ); */
SLsmg_gotorc( 0, 0 );
SLsmg_refresh();
@@ -194,26 +207,25 @@ void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr )
if( ! gt_Inited )
{
char * errmsg = '\r'+'\n'+"Internal error : screen driver initialization failure"+'\r'+'\n'+( char )0;
char *errmsg = '\r'+'\n'+"Internal error : screen driver initialization failure"+'\r'+'\n'+( char )0;
/* something went wrong - restore default settings */
SLang_reset_tty();
/* NOTE: a standard Harbour error should be generated here ! */
/* TODO: a standard Harbour error should be generated here ! */
write( iFilenoStderr, errmsg , strlen( errmsg ) );
exit( 20 );
}
}
/* *********************************************************************** */
void hb_gt_Exit( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Exit()"));
/*
NOTE: This is incompatible with Clipper
- on exit leave a cursor visible
*/
hb_mouse_Exit();
/* NOTE: This is incompatible with Clipper
- on exit leave a cursor visible */
if( s_sCursorStyle != SC_UNAVAIL )
hb_gt_SetCursorStyle( SC_NORMAL );
@@ -222,6 +234,59 @@ void hb_gt_Exit( void )
SLang_reset_tty();
}
/* *********************************************************************** */
USHORT hb_gt_GetScreenWidth( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenWidth()"));
return SLtt_Screen_Cols;
}
/* *********************************************************************** */
USHORT hb_gt_GetScreenHeight( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenHeight()"));
return SLtt_Screen_Rows;
}
/* *********************************************************************** */
SHORT hb_gt_Col( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Col()"));
return SLsmg_get_column();
}
/* *********************************************************************** */
SHORT hb_gt_Row( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Row()"));
return SLsmg_get_row();
}
/* *********************************************************************** */
void hb_gt_SetPos( SHORT iRow, SHORT iCol, SHORT iMethod )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetPos(%hd, %hd, %hd)", iRow, iCol, iMethod));
HB_SYMBOL_UNUSED( iMethod );
SLsmg_gotorc( iRow, iCol );
/* SLtt_goto_rc( iRow, iCol ); */ /* ??? */
if( s_uiDispCount == 0 )
SLsmg_refresh();
}
/* *********************************************************************** */
BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen )
{
ULONG ulCount;
@@ -250,10 +315,9 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen )
case HB_CHAR_LF:
col = 0;
/* This is a hack. OutStd() is done outside Slang and it
can't be tracked currently by Slang. This should be
changed in console.c
*/
/* This is a hack. Out<xxx>() is done outside Slang and
it can't be tracked currently by Slang. This should
be changed in console.c */
SLtt_write_string( "\r" );
if( row < SLtt_Screen_Rows - 1 )
row++;
@@ -280,53 +344,7 @@ BOOL hb_gt_AdjustPos( BYTE * pStr, ULONG ulLen )
return TRUE;
}
BOOL hb_gt_IsColor( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_IsColor()"));
return SLtt_Use_Ansi_Colors;
}
USHORT hb_gt_GetScreenWidth( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenWidth()"));
return SLtt_Screen_Cols;
}
USHORT hb_gt_GetScreenHeight( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetScreenHeight()"));
return SLtt_Screen_Rows;
}
void hb_gt_SetPos( SHORT iRow, SHORT iCol, SHORT iMethod )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetPos(%hd, %hd, %hd)", iRow, iCol, iMethod));
HB_SYMBOL_UNUSED( iMethod );
SLsmg_gotorc( iRow, iCol );
/* SLtt_goto_rc( iRow, iCol ); */ /* ??? */
if( s_uiDispCount == 0 )
SLsmg_refresh();
}
SHORT hb_gt_Col( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Col()"));
return SLsmg_get_column();
}
SHORT hb_gt_Row( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Row()"));
return SLsmg_get_row();
}
/* *********************************************************************** */
USHORT hb_gt_GetCursorStyle( void )
{
@@ -341,6 +359,8 @@ USHORT hb_gt_GetCursorStyle( void )
return( s_sCursorStyle );
}
/* *********************************************************************** */
void hb_gt_SetCursorStyle( USHORT uiStyle )
{
/* keyseq to define cursor shape under linux console */
@@ -348,7 +368,7 @@ void hb_gt_SetCursorStyle( USHORT uiStyle )
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetCursorStyle(%hu)", uiStyle));
/* TODO: How to set the shape of the cursor? */
/* TODO: How to set the shape of the cursor ? */
/* see ..\..\..\tests\working\cursrtst.prg for an explanation */
if( s_sCursorStyle == SC_UNAVAIL )
return;
@@ -358,6 +378,7 @@ void hb_gt_SetCursorStyle( USHORT uiStyle )
s_sCursorStyle = uiStyle;
SLtt_set_cursor_visibility( s_sCursorStyle != SC_NONE );
/* NOTE: cursor apearence works only under linux console */
if( s_linuxConsole )
{
switch( uiStyle )
@@ -380,8 +401,7 @@ void hb_gt_SetCursorStyle( USHORT uiStyle )
case SC_SPECIAL2:
/* TODO: find a proper sequqnce to set a cursor
to SC_SPECIAL2 under Linux console
*/
to SC_SPECIAL2 under Linux console */
cursDefseq[ 3 ] = '4';
break;
}
@@ -394,28 +414,45 @@ void hb_gt_SetCursorStyle( USHORT uiStyle )
}
}
/* *********************************************************************** */
BOOL hb_gt_IsColor( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_IsColor()"));
return SLtt_Use_Ansi_Colors;
}
/* *********************************************************************** */
static void hb_gt_xPutch( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE byChar )
{
unsigned char Pos, Mask;
SLsmg_Char_Type SLchar;
HB_TRACE(HB_TR_DEBUG, ("hb_gt_xPutch(%hu, %hu, %d, %i)", uiRow, uiCol, (int) byAttr, byChar));
/* build a Slang converted char - note we are clearing a high bit of color */
SLchar = SLSMG_BUILD_CHAR( s_convHighChars[ byChar ],
( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F );
Pos = ( unsigned char ) ( ( byChar & 0x7F ) >> 3 );
Mask = ( unsigned char ) ( 1 << ( byChar & 0x07 ) );
/* alternate char set */
if( byChar > 127 )
SLchar |= 0x8000;
/* this hack turns on Normal Char Set when we should draw nation char. */
/* build a Slang converted char - note we are clearing a high bit of color */
if( s_bUse_Alt_Char_Hack || !( s_IsNationChar[ Pos ] & Mask ) )
SLchar = s_convHighChars[ byChar ] | ( SLsmg_Char_Type )( ( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F ) << 8 );
else
SLchar = ( SLsmg_Char_Type )byChar | ( SLsmg_Char_Type )( ( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F ) << 8 );
SLsmg_gotorc( uiRow, uiCol );
SLsmg_write_raw( &SLchar, 1 );
}
/* *********************************************************************** */
void hb_gt_Puts( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE * pbyStr, ULONG ulLen )
{
ULONG i;
BYTE byChar;
unsigned char Pos, Mask;
SLsmg_Char_Type SLchar, * pScr;
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Puts(%hu, %hu, %d, %p, %lu)", uiRow, uiCol, (int) byAttr, pbyStr, ulLen));
@@ -427,13 +464,15 @@ void hb_gt_Puts( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE * pbyStr, ULONG u
/* next char to process */
byChar = *pbyStr++;
/* build a Slang converted char - note we are clearing a high bit of color */
SLchar = SLSMG_BUILD_CHAR( s_convHighChars[ byChar ],
( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F );
Pos = ( unsigned char ) ( ( byChar & 0x7F ) >> 3 );
Mask = ( unsigned char ) ( 1 << ( byChar & 0x07 ) );
/* alternate char set */
if( byChar > 127 )
SLchar |= 0x8000;
/* this hack turns on Normal Char Set when we should draw nation char. */
/* build a Slang converted char - note we are clearing a high bit of color */
if( s_bUse_Alt_Char_Hack || !( s_IsNationChar[ Pos ] & Mask ) )
SLchar = s_convHighChars[ byChar ] | ( SLsmg_Char_Type )( ( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F ) << 8 );
else
SLchar = ( SLsmg_Char_Type )byChar | ( SLsmg_Char_Type )( ( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F ) << 8 );
*( pScr + i ) = SLchar;
}
@@ -442,22 +481,21 @@ void hb_gt_Puts( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE * pbyStr, ULONG u
if( ulLen > 0 )
SLsmg_write_raw( pScr, ulLen );
/*
SLsmg_gotorc( uiRow, uiCol + ulLen );
if( s_uiDispCount == 0 )
SLsmg_refresh();
*/
hb_gt_SetPos( uiRow, uiCol + ulLen, HB_GT_SET_POS_AFTER );
hb_xfree( ( BYTE * )pScr );
}
/* *********************************************************************** */
int hb_gt_RectSize( USHORT rows, USHORT cols )
{
return rows * cols * sizeof( SLsmg_Char_Type );
}
/* *********************************************************************** */
void hb_gt_GetText( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbyDst )
{
int Cols;
@@ -478,6 +516,8 @@ void hb_gt_GetText( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight
SLsmg_gotorc( usSavRow, usSavCol );
}
/* *********************************************************************** */
void hb_gt_PutText( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbySrc )
{
int Cols;
@@ -495,15 +535,12 @@ void hb_gt_PutText( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight
pBuf += Cols;
++uiTop;
}
/*
SLsmg_gotorc( usSavRow, usSavCol );
if( s_uiDispCount == 0 )
SLsmg_refresh();
*/
hb_gt_SetPos( usSavRow, usSavCol, HB_GT_SET_POS_AFTER );
}
/* *********************************************************************** */
void hb_gt_SetAttribute( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE byAttr )
{
int Rows, Cols;
@@ -521,12 +558,13 @@ void hb_gt_SetAttribute( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT ui
SLsmg_refresh();
}
/* *********************************************************************** */
void hb_gt_Scroll( USHORT usTop, USHORT usLeft, USHORT usBottom, USHORT usRight, BYTE byAttr, SHORT iRows, SHORT iCols )
{
/* this work is based on gtdos.c, but changed to get scroll
worked well when scrolling horizontally. Clipper behaves
strange here.
*/
strange here. */
SHORT usSaveRow, usSaveCol;
USHORT uiSize;
@@ -587,6 +625,8 @@ void hb_gt_Scroll( USHORT usTop, USHORT usLeft, USHORT usBottom, USHORT usRight,
}
}
/* *********************************************************************** */
void hb_gt_DispBegin( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispBegin()"));
@@ -594,14 +634,22 @@ void hb_gt_DispBegin( void )
++s_uiDispCount;
}
/* *********************************************************************** */
void hb_gt_DispEnd()
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispEnd()"));
if( --s_uiDispCount == 0 )
/* is this compatible with Clipper ? */
if( s_uiDispCount > 0 )
--s_uiDispCount;
if( s_uiDispCount == 0 )
SLsmg_refresh();
}
/* *********************************************************************** */
BOOL hb_gt_SetMode( USHORT uiRows, USHORT uiCols )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetMode(%hu, %hu)", uiRows, uiCols));
@@ -613,6 +661,8 @@ BOOL hb_gt_SetMode( USHORT uiRows, USHORT uiCols )
return FALSE;
}
/* *********************************************************************** */
BOOL hb_gt_GetBlink()
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetBlink()"));
@@ -621,6 +671,8 @@ BOOL hb_gt_GetBlink()
return FALSE;
}
/* *********************************************************************** */
void hb_gt_SetBlink( BOOL bBlink )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetBlink(%d)", (int) bBlink));
@@ -629,6 +681,8 @@ void hb_gt_SetBlink( BOOL bBlink )
HB_SYMBOL_UNUSED( bBlink );
}
/* *********************************************************************** */
void hb_gt_Tone( double dFrequency, double dDuration )
{
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Tone(%lf, %lf)", dFrequency, dDuration));
@@ -640,37 +694,44 @@ void hb_gt_Tone( double dFrequency, double dDuration )
SLtt_beep();
}
/* *********************************************************************** */
char * hb_gt_Version( void )
{
return "Harbour Terminal: Slang";
}
/* *********************************************************************** */
USHORT hb_gt_DispCount()
{
return s_uiDispCount;
}
/* *********************************************************************** */
void hb_gt_Replicate( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE byChar, ULONG ulLen )
{
ULONG i;
unsigned char Pos, Mask;
SLsmg_Char_Type SLchar, * pScr;
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Replicate(%hu, %hu, %i, %i, %lu)", uiRow, uiCol, byAttr, byChar, nLength));
pScr = ( SLsmg_Char_Type * ) hb_xgrab( ( ulLen + 1 ) * sizeof( SLsmg_Char_Type ) );
Pos = ( unsigned char ) ( ( byChar & 0x7F ) >> 3 );
Mask = ( unsigned char ) ( 1 << ( byChar & 0x07 ) );
/* this hack turns on Normal Char Set when we should draw nation char. */
/* build a Slang converted char - note we are clearing a high bit of color */
if( s_bUse_Alt_Char_Hack || !( s_IsNationChar[ Pos ] & Mask ) )
SLchar = s_convHighChars[ byChar ] | ( SLsmg_Char_Type )( ( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F ) << 8 );
else
SLchar = ( SLsmg_Char_Type )byChar | ( SLsmg_Char_Type )( ( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F ) << 8 );
for( i = 0; i < ulLen; i++ )
{
/* build a Slang converted char - note we are clearing a high bit of color */
SLchar = SLSMG_BUILD_CHAR( s_convHighChars[ byChar ],
( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F );
/* alternate char set */
if( byChar > 127 )
SLchar |= 0x8000;
*( pScr + i ) = SLchar;
}
SLsmg_gotorc( uiRow, uiCol );
@@ -678,21 +739,15 @@ void hb_gt_Replicate( USHORT uiRow, USHORT uiCol, BYTE byAttr, BYTE byChar, ULON
{
SLsmg_write_raw( pScr, ulLen );
/* this should not be needed here.
hb_gtRepChar() should set this for us
*/
/*
SLsmg_gotorc( uiRow, uiCol + ulLen );
if( s_uiDispCount == 0 )
SLsmg_refresh();
*/
/* this should not be needed here. hb_gtRepChar() should set this for us */
hb_gt_SetPos( uiRow, uiCol + ulLen, HB_GT_SET_POS_AFTER );
}
hb_xfree( ( BYTE * ) pScr );
}
/* *********************************************************************** */
USHORT hb_gt_Box( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight,
BYTE *szBox, BYTE byAttr )
{
@@ -701,6 +756,12 @@ USHORT hb_gt_Box( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight,
USHORT uiHeight;
USHORT uiWidth;
/* a box drawing hack */
BOOL SaveUseAltChar = s_bUse_Alt_Char_Hack;
/* a box drawing hack */
s_bUse_Alt_Char_Hack = TRUE;
/* Ensure that box is drawn from top left to bottom right. */
if( uiTop > uiBottom )
{
@@ -736,7 +797,6 @@ USHORT hb_gt_Box( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight,
hb_gt_xPutch( uiRow, uiRight, byAttr, szBox[ 2 ] ); /* Upper right corner */
if( szBox[ 8 ] && uiHeight > 2 && uiWidth > 2 )
{
for( uiRow = uiTop + 1; uiRow < uiBottom; uiRow++ )
{
uiCol = uiLeft;
@@ -744,16 +804,13 @@ USHORT hb_gt_Box( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight,
hb_gt_Replicate( uiRow, uiCol, byAttr, szBox[ 8 ], uiRight - uiLeft - 1 ); /* Fill */
hb_gt_xPutch( uiRow, uiRight, byAttr, szBox[ 3 ] ); /* Right side */
}
}
else
{
for( uiRow = ( uiWidth > 1 ? uiTop + 1 : uiTop ); uiRow < ( uiWidth > 1 ? uiBottom : uiBottom + 1 ); uiRow++ )
{
hb_gt_xPutch( uiRow, uiLeft, byAttr, szBox[ 7 ] ); /* Left side */
if( uiWidth > 1 )
hb_gt_xPutch( uiRow, uiRight, byAttr, szBox[ 3 ] ); /* Right side */
}
}
if( uiHeight > 1 && uiWidth > 1 )
{
@@ -771,31 +828,52 @@ USHORT hb_gt_Box( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight,
hb_gt_DispEnd();
/* a box drawing hack */
s_bUse_Alt_Char_Hack = SaveUseAltChar;
return 0;
}
/* *********************************************************************** */
USHORT hb_gt_BoxD( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbyFrame, BYTE byAttr )
{
return hb_gt_Box( uiTop, uiLeft, uiBottom, uiRight, pbyFrame, byAttr );
}
/* *********************************************************************** */
USHORT hb_gt_BoxS( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbyFrame, BYTE byAttr )
{
return hb_gt_Box( uiTop, uiLeft, uiBottom, uiRight, pbyFrame, byAttr );
}
/* *********************************************************************** */
USHORT hb_gt_HorizLine( USHORT uiRow, USHORT uiLeft, USHORT uiRight, BYTE byChar, BYTE byAttr )
{
BOOL SaveUseAltChar = s_bUse_Alt_Char_Hack;
/* a box drawing hack */
s_bUse_Alt_Char_Hack = TRUE;
if( uiLeft < uiRight )
hb_gt_Replicate( uiRow, uiLeft, byAttr, byChar, uiRight - uiLeft + 1 );
else
hb_gt_Replicate( uiRow, uiRight, byAttr, byChar, uiLeft - uiRight + 1 );
/* box drawing hack */
s_bUse_Alt_Char_Hack = SaveUseAltChar;
return 0;
}
/* *********************************************************************** */
USHORT hb_gt_VertLine( USHORT uiCol, USHORT uiTop, USHORT uiBottom, BYTE byChar, BYTE byAttr )
{
USHORT uRow;
BOOL SaveUseAltChar = s_bUse_Alt_Char_Hack;
if( uiTop <= uiBottom )
uRow = uiTop;
@@ -805,25 +883,28 @@ USHORT hb_gt_VertLine( USHORT uiCol, USHORT uiTop, USHORT uiBottom, BYTE byChar,
uiBottom = uiTop;
}
/* a box drawing hack */
s_bUse_Alt_Char_Hack = TRUE;
while( uRow <= uiBottom )
hb_gt_xPutch( uRow++, uiCol, byAttr, byChar );
/*
SLsmg_gotorc( uiBottom + 1, uiCol );
if( s_uiDispCount == 0 )
SLsmg_refresh();
*/
/* a box drawing hack */
s_bUse_Alt_Char_Hack = SaveUseAltChar;
hb_gt_SetPos( uiBottom + 1, uiCol, HB_GT_SET_POS_AFTER );
return 0;
}
/* ------------------------------------------------------ */
/* *********************************************************************** */
/* NOTE: these two are for prepare Slang to temporary
finish its work. They should be called from run.c.
They are not re-enrant ???.
*/
They are not re-enrant ???. */
/* *********************************************************************** */
BOOL hb_gt_Suspend()
{
if( ! s_bSuspended )
@@ -838,45 +919,49 @@ BOOL hb_gt_Suspend()
return s_bSuspended;
}
/* *********************************************************************** */
BOOL hb_gt_Resume()
{
if( s_bSuspended &&
SLsmg_resume_smg() != -1 &&
hb_gt_Init_Terminal( 1 ) != -1 ) /* reinitialize a terminal */
hb_gt_Init_Terminal( 1 ) != -1
) /* reinitialize a terminal */
SLsmg_refresh();
{
s_bSuspended = FALSE;
}
s_bSuspended = FALSE;
return( !s_bSuspended );
}
/* *********************************************************************** */
BOOL hb_gt_PreExt()
{
SLsmg_refresh();
return TRUE;
}
/* *********************************************************************** */
BOOL hb_gt_PostExt()
{
return TRUE;
}
/* ------------------------------------------------------ */
/* *********************************************************************** */
static void hb_gt_build_conv_tabs()
{
int i, fg, bg;
#ifndef IBMPC_SYSTEM
int len;
char *p, ch;
#endif
int i, fg, bg, len;
unsigned char *p, ch;
SLsmg_Char_Type SLch;
/* COMPATIBILITY: Slang uses bit 0x8000 as an alternate
char mask so it leaves us only 128 possible fgbg colors.
(see Notes in Slang sources). This is incompatible with
Clipper. Slang uses color 0 as a normal color and a
color 1 as a reverse one, leaving us only 126 fgbg.
Clipper. Slang also uses color 0 as a normal color and
a color 1 as a reverse one, leaving us only 126 fgbg.
*/
/* init colors - color 0 and 1 are normal and
reverse color in Slang. We can't use them
@@ -888,59 +973,81 @@ static void hb_gt_build_conv_tabs()
/* leave 0 and 1 for Slang library. Shift color number by 2 */
SLtt_set_color( i + SLANG_RESERVED_COLORS, ( char * ) NULL, s_colorNames[ fg ], s_colorNames[ bg ] );
/* SLsmg_set_color(i + SLANG_RESERVED_COLORS); */
}
/* Slang normal and reverse color */
SLtt_set_color( 0, ( char * ) NULL, s_colorNames[ 7 ], s_colorNames[ 0 ] );
SLtt_set_color( 1, ( char * ) NULL, s_colorNames[ 0 ], s_colorNames[ 7 ] );
/* build an alternate chars table */
/* build an conversion chars table */
for( i = 0; i < 32; i++ )
/* under Unix control-chars are not visible in a general meaning */
s_convHighChars[ i ] = '.';
for( i = 32; i < 256; i++ )
s_convHighChars[ i ] = i;
s_convHighChars[ i ] = ( SLsmg_Char_Type ) '.';
/* s_convHighChars[ i ] = ( ( SLsmg_Char_Type ) i ) | 0x8000; */
for( i = 32; i < 128; i++ )
/* lower 128-32 chars are from normal char set */
s_convHighChars[ i ] = ( SLsmg_Char_Type ) i;
for( i = 128; i < 256; i++ )
/* upper 128 chars are from alternate char set */
s_convHighChars[ i ] = ( ( SLsmg_Char_Type ) i ) | 0x8000;
#ifndef IBMPC_SYSTEM
/* init an alternate chars table */
if( ( p = SLtt_Graphics_Char_Pairs ) )
{
len = strlen( p );
for( i = 0; i < len; i++ )
/* alternate char set should be even */
if( ( len != ( ( len / 2 ) * 2 ) ) && ( len > 0 ) )
--len;
for( i = 0; i < len / 2; i++ )
{
ch = *p++;
/* is this really nessecary ? */
ch &= 0x7F;
SLch = ( ( SLsmg_Char_Type )( *p ) ) | 0x8000;
switch( ch )
{
case SLSMG_HLINE_CHAR : s_convHighChars[ 196 ] = *p; break;
case SLSMG_VLINE_CHAR : s_convHighChars[ 179 ] = *p; break;
case SLSMG_ULCORN_CHAR : s_convHighChars[ 218 ] = *p; break;
case SLSMG_URCORN_CHAR : s_convHighChars[ 191 ] = *p; break;
case SLSMG_LLCORN_CHAR : s_convHighChars[ 192 ] = *p; break;
case SLSMG_LRCORN_CHAR : s_convHighChars[ 217 ] = *p; break;
case SLSMG_CKBRD_CHAR : s_convHighChars[ 176 ] = *p; break;
case SLSMG_RTEE_CHAR : s_convHighChars[ 180 ] = *p; break;
case SLSMG_LTEE_CHAR : s_convHighChars[ 195 ] = *p; break;
case SLSMG_UTEE_CHAR : s_convHighChars[ 194 ] = *p; break;
case SLSMG_DTEE_CHAR : s_convHighChars[ 193 ] = *p; break;
case SLSMG_PLUS_CHAR : s_convHighChars[ 197 ] = *p; break;
case SLSMG_HLINE_CHAR : s_convHighChars[ 196 ] = SLch; break;
case SLSMG_VLINE_CHAR : s_convHighChars[ 179 ] = SLch; break;
case SLSMG_ULCORN_CHAR : s_convHighChars[ 218 ] = SLch; break;
case SLSMG_URCORN_CHAR : s_convHighChars[ 191 ] = SLch; break;
case SLSMG_LLCORN_CHAR : s_convHighChars[ 192 ] = SLch; break;
case SLSMG_LRCORN_CHAR : s_convHighChars[ 217 ] = SLch; break;
case SLSMG_CKBRD_CHAR : s_convHighChars[ 176 ] = SLch; break;
case SLSMG_RTEE_CHAR : s_convHighChars[ 180 ] = SLch; break;
case SLSMG_LTEE_CHAR : s_convHighChars[ 195 ] = SLch; break;
case SLSMG_UTEE_CHAR : s_convHighChars[ 194 ] = SLch; break;
case SLSMG_DTEE_CHAR : s_convHighChars[ 193 ] = SLch; break;
case SLSMG_PLUS_CHAR : s_convHighChars[ 197 ] = SLch; break;
/* TODO: need some smart here */
/*
case SLSMG_DIAMOND_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_DEGREE_CHAR; : s_convHighChars[ ] = *p; break;
case SLSMG_PLMINUS_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_BULLET_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_LARROW_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_RARROW_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_DARROW_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_UARROW_CHAR : s_convHighChars[ ] = *p; break;
case SLSMG_DEGREE_CHAR; : s_convHighChars[ ] = SLch; break;
case SLSMG_PLMINUS_CHAR : s_convHighChars[ ] = SLch; break;
case SLSMG_BULLET_CHAR : s_convHighChars[ ] = SLch; break;
*/
case SLSMG_BOARD_CHAR : s_convHighChars[ 178 ] = *p; break;
case SLSMG_BLOCK_CHAR : s_convHighChars[ 219 ] = *p; break;
case SLSMG_DIAMOND_CHAR : s_convHighChars[ 04 ] = SLch;
break;
case SLSMG_LARROW_CHAR : s_convHighChars[ 17 ] = SLch;
s_convHighChars[ 27 ] = SLch;
break;
case SLSMG_RARROW_CHAR : s_convHighChars[ 16 ] = SLch;
s_convHighChars[ 26 ] = SLch;
break;
case SLSMG_DARROW_CHAR : s_convHighChars[ 25 ] = SLch;
s_convHighChars[ 31 ] = SLch;
break;
case SLSMG_UARROW_CHAR : s_convHighChars[ 24 ] = SLch;
s_convHighChars[ 30 ] = SLch;
break;
case SLSMG_BOARD_CHAR : s_convHighChars[ 178 ] = SLch;
break;
case SLSMG_BLOCK_CHAR : s_convHighChars[ 219 ] = SLch;
break;
}
p++;
++p;
}
}
@@ -968,5 +1075,40 @@ static void hb_gt_build_conv_tabs()
s_convHighChars[ 202 ] = s_convHighChars[ 193 ];
s_convHighChars[ 206 ] = s_convHighChars[ 197 ];
}
#endif
/* init national chars */
if( ( p = getenv( hb_NationCharsEnvName ) ) )
{
unsigned char Pos, Mask;
len = strlen( p );
/* a len of definition of National chars should be even */
if( ( len != ( ( len / 2 ) * 2 ) ) && ( len > 0 ) )
--len;
/* no more than 128 National chars are allowed */
if( len > 256 ) len = 256;
/* the first element contains a number of Dead keys defined in an ENVAR */
s_convKDeadKeys[ 0 ] = ( unsigned char ) ( len / 2 );
for( i = 0; i < len / 2; i++ )
{
ch = *p++;
s_convKDeadKeys[ 2 * i + 1 ] = ch;
s_convKDeadKeys[ 2 * i + 2 ] = *p;
Pos = ( unsigned char ) ( ( *p & 0x7F ) >> 3 );
Mask = ( unsigned char ) ( 1 << ( *p & 0x07 ) );
s_IsNationChar[ Pos ] |= Mask;
++p;
}
/*
for( i=0; i <= ( ( int ) s_convKDeadKeys[ 0 ] ) * 2; i++ )
fprintf( stderr, "%3d %c\r\n", i, s_convKDeadKeys[ i ] );
ch=getc( stdin );
*/
}
}
/* *********************************************************************** */

View File

@@ -4,7 +4,7 @@
/*
* Harbour Project source code:
* Video subsystem based on Slang screen library.
* Keyboard subsystem based on Slang screen library.
*
* Copyright 2000 Marek Paliwoda <paliwoda@inetia.pl>
* www - http://www.harbour-project.org
@@ -35,6 +35,7 @@
/* NOTE: User programs should never call this layer directly! */
/* *********************************************************************** */
#ifdef __linux__
#include <slang/slang.h>
@@ -49,57 +50,61 @@
#include <sys/vtkd.h>
#endif
#ifndef IBMPC_SYSTEM
#include <termios.h> /* we're assuming target has termios - should be better done */
#endif
#include <termios.h> /* we're assuming target has termios - should be better done */
#include "hbapigt.h"
#include "inkey.ch"
/* ----------------------------------------------- */
/* abort key is Ctrl+C on Unix (arbitrary chosen), on Dos it works as Alt+C (strange !) */
#ifdef OS_UNIX_COMPATIBLE
#define CTRL_C 3
#else
#define CTRL_C 46
#endif
#define HB_GT_ABORT_KEY CTRL_C
/* 2/10 of a second waiting for the next char after ESC */
#define ESC_TIMEOUT 2
/* *********************************************************************** */
/* keyboard states - these should be taken
from system includes, not be hard coded
*/
from system includes, not be hard coded */
#if defined(__linux__)
#define SHIFT_PRESSED 1
#define ALTR_PRESSED 2
#define CONTROL_PRESSED 4
#define ALTL_PRESSED 8
#define ALT_PRESSED ( ALTL_PRESSED || ALTR_PRESSED )
#define ALT_PRESSED ALTL_PRESSED
#elif defined(M_UNIX) /* SCO */
#define SHIFT_PRESSED 1
#define ALTR_PRESSED 8
#define CONTROL_PRESSED 2
#define ALTL_PRESSED 4
#define ALT_PRESSED ( ALTL_PRESSED || ALTR_PRESSED )
#define ALT_PRESSED ALTL_PRESSED
#else /* we don't know how to do this */
#define SHIFT_PRESSED 0
#define ALTR_PRESSED 0
#define CONTROL_PRESSED 0
#define ALTL_PRESSED 0
#define ALT_PRESSED ( ALTL_PRESSED || ALTR_PRESSED )
#define ALT_PRESSED ALTL_PRESSED
#endif
#define HB_GT_KBD_MODIF_MASK \
( ( SHIFT_PRESSED | CONTROL_PRESSED | ALTL_PRESSED ) << 16 )
/* extra keysyms definitions */
#define SL_KEY_MAX 1000
#define SL_KEY_ESC SL_KEY_MAX + 1
#define SL_KEY_ALT_L( ch ) ( SL_KEY_MAX + ( ( unsigned int ) ch ) )
#define SL_KEY_NUM_5 SL_KEY_B2 /* this is checked explicitly */
#define SL_KEY_MAX ( ( unsigned int ) 0x1000 )
#define SL_KEY_ESC ( SL_KEY_MAX + 1 )
#define SL_KEY_ALT( ch ) ( SL_KEY_MAX + ( ( unsigned int ) ch ) )
/* abort key is Ctrl+C on Unix ( but Alt+C on Linux console ) */
static int s_hb_gt_Abort_Key = K_CTRL_C;
/* *********************************************************************** */
/* indicates that screen size has changed */
extern BOOL hb_gt_sln_bScreen_Size_Changed;
/* DeadKey definition's ENVVAR name. This EnvVar contains */
/* an ASCII value of a key, which serves as a DeadKey */
unsigned char *hb_DeadKeyEnvName = "HRBNATIONDEADKEY";
/* a table for DeadKeys. The first element contains a number of defined keys */
unsigned char s_convKDeadKeys[ 257 ]; /* it should be allocated by hb_xalloc() */
/* contains an integer value of a DeadKey or -1 */
int hb_DeadKey = -1;
static BOOL s_linuxConsole = FALSE;
static BOOL s_underXTerm = FALSE;
@@ -108,127 +113,106 @@ int hb_gt_Kbd_State();
/* key translations tables - notice problems with compilation after changes */
#include "keytrans.c"
/* *********************************************************************** */
static void hb_gt_Init_KeyTranslat()
{
char ch, keyname[ SLANG_MAX_KEYMAP_KEY_SEQ + 1 ];
int keynum, i;
int keynum, i;
#ifdef IBMPC_SYSTEM
char * keyseq;
/* on Unix systems ESC is a special key so let
assume ESC is a doble pressed ESC key */
SLkp_define_keysym( "^[^[", SL_KEY_ESC );
/* try to define Shft-Fn and Ctrl-Fn keys.
Because we assume terminal has only 10 Fkeys
so F11-F30 is generated with Shift & Ctrl.
This is not guaranteed to work in all cases */
keynum = 11;
keyname[ 0 ] = '^';
keyname[ 1 ] = '@';
keyname[ 3 ] = 0;
keyname[ 0 ] = 'F';
keyname[ 2 ] = 0;
/* define Shft/Ctrl/Alt+Fn on DOS - these are hard coded in Slang */
for( ch = 0x54; ch <= 0x71; ch++ )
/* Shft & Ctrl FKeys definition takes place in two
phases : from '1' to '9' and from 'A' to 'K' */
for( i = 1; i <= 2; i++ )
{
keyname[ 2 ] = ch;
SLkp_define_keysym( keyname, SL_KEY_F( keynum ) );
keynum++;
for( ch = ( i == 1 ? '1' : 'A' ); ch <= ( i == 1 ? '9' : 'K' ); ch++ )
{
keyname[ 1 ] = ch;
keyseq = SLtt_tgetstr( keyname );
if( ( keyseq != NULL ) && ( keyseq[ 0 ] != 0 ) )
SLkp_define_keysym( keyseq, SL_KEY_F( keynum ) );
keynum++;
}
}
/* define Alt+Key on DOS - these are hard coded in Slang */
i = 0;
while( i < sizeof( transDosScanCodeTab ) )
/* if we are on linux console pressing Alt generates ^[ before sequence */
if( s_linuxConsole || s_underXTerm )
{
i++;
if( transDosScanCodeTab[ i ] < 32 )
char AltChars[][ 2 ] =
{
keyname[ 2 ] = '^';
keyname[ 3 ] = transDosScanCodeTab[ i ] + 'A' - 1;
keyname[ 4 ] = 0;
}
/*
else if( transDosScanCodeTab[ i ] >= 127 )
{
sprintf( &keyname[ 2 ], "\\x%02X", transDosScanCodeTab[ i ] );
keyname[ 6 ] = 0;
}
*/
else
{
keyname[ 2 ] = transDosScanCodeTab[ i ];
keyname[ 3 ] = 0;
}
SLkp_define_keysym( keyname, SL_KEY_ALT_L( transDosScanCodeTab[ i - 1 ] ) );
i++;
}
{ '0', '9' },
{ 'A', 'Z' },
{ 'a', 'z' }
};
#else
{
char * keyseq;
/* on Unix systems ESC is a special key so let
assume ESC is also a doble pressed ESCkey
*/
SLkp_define_keysym( "^[^[", SL_KEY_ESC );
/* try to define Shft-Fn and Ctrl-Fn keys.
Because we assume terminal has only 10 Fkeys
so F11-F30 is generated with Shift & Ctrl.
This is not guaranteed to work in all cases
*/
keynum = 11;
keyname[ 0 ] = 'F';
keyname[ 0 ] = 033;
keyname[ 2 ] = 0;
/* Shft & Ctrl FKeys definition takes place in two
phases : from '1' to '9' and from 'A' to 'K'
*/
for( i = 1; i <= 2; i++ )
/* Alt+Letter & Alt+digit definition takes place in three phases :
from '0' to '9', from 'A' to 'Z' and from 'a' to 'z' */
for( i = 0; i < 3; i++ )
{
for( ch = ( i == 1 ? '1' : 'A' ); ch <= ( i == 1 ? '9' : 'K' ); ch++ )
for( ch = AltChars[ i ][ 0 ]; ch <= AltChars[ i ][ 1 ]; ch++ )
{
/* fprintf( stderr, "%d %c\n", i, ch ); */
keyname[ 1 ] = ch;
keyseq = SLtt_tgetstr( keyname );
if( ( keyseq != NULL ) && ( keyseq[ 0 ] != 0 ) )
SLkp_define_keysym( keyseq, SL_KEY_F( keynum ) );
keynum++;
}
}
/* if we are on linux console pressing Alt generates ^[ before sequence */
if( s_linuxConsole || s_underXTerm )
{
keyname[ 0 ] = 033;
keyname[ 2 ] = 0;
/* Alt+Letter & Alt+digit definition takes place in
two phases : from '0' to '9' and from 'A' to 'Z'
*/
for( i = 1; i <= 2; i++ )
{
for( ch = ( i == 1 ? '0' : 'A' ); ch <= ( i == 1 ? '9' : 'Z' ); ch++ )
{
keyname[ 1 ] = ch;
/* QUESTION: why Slang reports error for defining Alt+O ???.
Have I any error in key definitiions ???
*/
if( ch != 'O' )
SLkp_define_keysym( keyname, SL_KEY_ALT_L( ch ) );
keyname[ 1 ] = ( ch + ' ' );
SLkp_define_keysym( keyname, SL_KEY_ALT_L( ch + ' ' ) );
}
/* QUESTION: why Slang reports error for defining Alt+O ???.
Have I any error in key definitiions ??? */
if( ch != 'O' )
SLkp_define_keysym( keyname, SL_KEY_ALT( ch ) );
}
}
/* five on numeric console */
/* SLkp_define_keysym( "^[[G", SL_KEY_NUM_5 ); */
}
#endif
}
/* *********************************************************************** */
int hb_gt_Init_Terminal( int phase )
{
#ifndef IBMPC_SYSTEM
struct termios newTTY;
#endif
unsigned char *p;
int ret = 0;
/* Ctrl-C to abort, no flow-control, no output processing */
if( SLang_init_tty( HB_GT_ABORT_KEY, 0, 0 ) != -1 )
if( phase == 0 )
{
/* an uncertain way to check if we run under linux console */
s_linuxConsole = ( ! strncmp( getenv( "TERM" ), "linux", 5 ) );
/* an uncertain way to check if we run under linux xterm */
s_underXTerm = ( strstr( getenv( "TERM" ), "xterm" ) != NULL );
/* for Linux console and for Linux xterm */
if( s_linuxConsole || s_underXTerm )
s_hb_gt_Abort_Key = K_ALT_C;
/* get Dead key definition */
if( ( p = getenv( hb_DeadKeyEnvName ) ) )
{
int len = strlen( p );
if( len > 0 )
hb_DeadKey = ( int ) *p;
}
}
/* Ctrl-C to abort, no flow-control, no output processing */
if( SLang_init_tty( s_hb_gt_Abort_Key, 0, 0 ) != -1 )
{
#ifndef IBMPC_SYSTEM
/* do missing disable of start/stop processing */
if( tcgetattr( SLang_TT_Read_FD, &newTTY ) == 0 )
{
@@ -238,35 +222,32 @@ int hb_gt_Init_Terminal( int phase )
if( tcsetattr( SLang_TT_Read_FD, TCSADRAIN, &newTTY ) == 0 )
/* everything looks ok so far */
#endif
ret = 1;
#ifndef IBMPC_SYSTEM
}
#endif
}
/* first time init phase - we don't want this
after return from system command ( see run.c )
*/
/* first time init phase - we don't want this after
return from system command ( see run.c ) */
if( ret && ( phase == 0 ) )
{
/* an uncertain way to check if we run under linux console */
s_linuxConsole = ( ! strncmp( getenv( "TERM" ), "linux", 5 ) );
/* an uncertain way to check if we run under xterm */
s_underXTerm = ( strstr( getenv( "TERM" ), "xterm" ) != NULL );
/* define keyboard translations */
hb_gt_Init_KeyTranslat();
/* for binary search of key translations */
hb_gt_SortKeyTrans();
}
return ret;
}
/* *********************************************************************** */
#undef DO_LOCAL_DEBUG
/* #define DO_LOCAL_DEBUG */
int hb_gt_ReadKey( HB_inkey_enum eventmask )
{
unsigned int ch, kbdflags;
static int InDeadState = FALSE;
unsigned int ch, tmp, kbdflags;
#ifdef DO_LOCAL_DEBUG
USHORT savy, savx;
#endif
@@ -293,24 +274,11 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask )
if( SLang_input_pending( 0 ) > 0 )
{
#if HB_GT_KBD_MODIF_MASK
kbdflags = hb_gt_Kbd_State();
/* ------- one key ESC key handling ----------------- */
/* NOTE: This will probably not work on slow terminals
or on a very busy lines (i.e. modem lines )
*/
ch = SLang_getkey();
if( ch == 033 ) /* escape */
{
if( 0 == SLang_input_pending( ESC_TIMEOUT ) )
return 033;
}
SLang_ungetkey( ch );
/* ------------------------------------------------- */
#else
kbdflags = 0;
#endif
ch = SLkp_getkey();
@@ -321,64 +289,46 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask )
#ifdef DO_LOCAL_DEBUG
hb_gtGetPos( &savy, &savx );
SLsmg_gotorc( 23, 0 );
SLsmg_printf( "%d %d ", ch, kbdflags );
SLsmg_printf( " %8x %d ", ch, kbdflags );
SLsmg_gotorc( savy, savx );
#endif
/* user AbortKey break */
if( ch == HB_GT_ABORT_KEY )
if( ch == s_hb_gt_Abort_Key )
return HB_BREAK_FLAG;
if( ch < 32 ) /* control characters - simply return */
return ch;
else if( ( ch >= 32 ) && ( ch < 256 ) ) /* normal characters ? */
/* Dead key handling */
if( InDeadState )
{
if( kbdflags & ALT_PRESSED )
{
/* lower to upper case */
if( ( ch >= 'a' ) && ( ch <= 'z' ) )
ch -= ' ';
/* alt + letter */
if( ( ch >= 'A' ) && ( ch <= 'Z' ) )
/* returned value is next in a table */
return transAltKeyLetterTab[ ( ch - 'A' ) * 2 + 1 ];
/* alt + digit */
if( ( ch >= '0' ) && ( ch <= '9' ) )
/* returned value is next in a table */
return transAltKeyDigitTab[ ( ch - '0' ) * 2 + 1 ];
}
return ch;
InDeadState = FALSE;
if( ch == hb_DeadKey ) /* double press Dead key */
return ch;
for( i=0; i < ( int ) s_convKDeadKeys[ 0 ]; i++ )
if( ( int ) s_convKDeadKeys[ 2 * i + 1 ] == ch )
return ( int ) s_convKDeadKeys[ 2 * i + 2 ];
return 0;
}
else if( ch == hb_DeadKey )
{
/* entering Dead key state */
InDeadState = TRUE;
return 0;
}
/* standard Slang keys */
else if( ( ch >= 256 ) && ( ch <= SL_KEY_ESC ) )
/* any special key ? */
if( ( tmp = ( ch | ( kbdflags << 16 ) ) ) > 256 )
{
for( i = 0; i < ( sizeof( transKeyFunTab ) / sizeof( int ) ); i++ )
tmp = hb_gt_FindKeyTrans( tmp );
if( tmp == 0 )
{
if( transKeyFunTab[ i++ ] == ch )
return transKeyFunTab[ i ];
tmp = hb_gt_FindKeyTrans( ch );
/* TOFIX: this can generate problems with values returned */
if( tmp == 0 && ch < 256 ) tmp = ch;
}
return tmp;
}
/* Linux/Dos Alt+A-Z keys */
else if( ( ch >= SL_KEY_ALT_L( 'A' ) ) && ( ch <= SL_KEY_ALT_L( 'Z' ) ) )
/* returned value is next in a table */
return transAltKeyLetterTab[ ( ch - SL_KEY_MAX - 'A' ) * 2 + 1 ];
/* Linux Alt+a-z keys - lower to upper conersion */
else if( ( ch >= SL_KEY_ALT_L( 'a' ) ) && ( ch <= SL_KEY_ALT_L( 'z' ) ) )
/* returned value is next in a table */
return transAltKeyLetterTab[ ( ch - SL_KEY_MAX - ' ' - 'A' ) * 2 + 1 ];
/* Linux/Dos Alt+0-9 keys */
else if( ( ch >= SL_KEY_ALT_L( '0' ) ) && ( ch <= SL_KEY_ALT_L( '9' ) ) )
/* returned value is next in a table */
return transAltKeyDigitTab[ ( ch - SL_KEY_MAX - '0' ) * 2 + 1 ];
/* standard key */
return ch;
}
}
@@ -386,6 +336,8 @@ int hb_gt_ReadKey( HB_inkey_enum eventmask )
return 0;
}
/* *********************************************************************** */
static int hb_gt_try_get_Kbd_State()
{
#if defined(__linux__)
@@ -402,22 +354,25 @@ static int hb_gt_try_get_Kbd_State()
int modifiers = 0;
int IOcommand = 0;
if( ioctl( 0, TCGETSC, &modifiers ) >= 0 )
if( ioctl( 0, TCGETSC, &IOcommand ) >= 0 )
{
if( modifiers == KB_XSCANCODE )
/* if keyboard is not in SCANCODE mode */
if( IOcommand == KB_XSCANCODE )
{
/* try to set it to SCANCODE mode */
IOcommand = KB_ISSCANCODE;
if( ioctl( 0, TCSETSC, &IOcommand ) >= 0 )
{
/* if SCANCODE mode is set corectly try get KBD state */
if( ioctl( 0, KDGKBSTATE, &modifiers ) < 0 )
modifiers = 0;
}
else modifiers = 0;
IOcommand = KB_XSCANCODE;
if( ioctl( 0, TCSETSC, &IOcommand ) < 0 )
modifiers = 0;
/* turn a keyboard to a normal mode ( translation mode ) */
IOcommand = KB_XSCANCODE;
( void ) ioctl( 0, TCSETSC, &IOcommand )
}
}
/* keyboard is already in SCANCODE mode */
else if( ioctl( 0, KDGKBSTATE, &modifiers ) < 0 )
modifiers = 0;
@@ -428,23 +383,32 @@ static int hb_gt_try_get_Kbd_State()
return 0;
}
/* *********************************************************************** */
int hb_gt_Shft_Pressed()
{
return ( hb_gt_try_get_Kbd_State() & SHIFT_PRESSED ) != 0;
}
/* *********************************************************************** */
int hb_gt_Ctrl_Pressed()
{
return ( hb_gt_try_get_Kbd_State() & CONTROL_PRESSED ) != 0;
}
/* *********************************************************************** */
int hb_gt_Alt_Pressed()
{
return ( hb_gt_try_get_Kbd_State() & ALT_PRESSED ) != 0;
}
/* *********************************************************************** */
int hb_gt_Kbd_State()
{
return hb_gt_try_get_Kbd_State();
}
/* *********************************************************************** */

View File

@@ -4,7 +4,7 @@
/*
* Harbour Project source code:
* Video subsystem based on Slang screen library.
* Keyboard subsystem based on Slang screen library.
*
* Copyright 2000 Marek Paliwoda <paliwoda@inetia.pl>
* www - http://www.harbour-project.org
@@ -33,99 +33,414 @@
*
*/
/* a table of function keys translation */
static int transKeyFunTab[] =
{
SL_KEY_DOWN, K_DOWN,
SL_KEY_UP, K_UP,
SL_KEY_LEFT, K_LEFT,
SL_KEY_RIGHT, K_RIGHT,
SL_KEY_HOME, K_HOME,
SL_KEY_END, K_END,
SL_KEY_BACKSPACE, K_BS,
SL_KEY_IC, K_INS,
SL_KEY_DELETE, K_DEL,
SL_KEY_NPAGE, K_PGDN,
SL_KEY_PPAGE, K_PGUP,
SL_KEY_ESC, K_ESC,
SL_KEY_F(1), K_F1,
SL_KEY_F(2), K_F2,
SL_KEY_F(3), K_F3,
SL_KEY_F(4), K_F4,
SL_KEY_F(5), K_F5,
SL_KEY_F(6), K_F6,
SL_KEY_F(7), K_F7,
SL_KEY_F(8), K_F8,
SL_KEY_F(9), K_F9,
SL_KEY_F(10), K_F10,
SL_KEY_F(11), K_SH_F1,
SL_KEY_F(12), K_SH_F2,
SL_KEY_F(13), K_SH_F3,
SL_KEY_F(14), K_SH_F4,
SL_KEY_F(15), K_SH_F5,
SL_KEY_F(16), K_SH_F6,
SL_KEY_F(17), K_SH_F7,
SL_KEY_F(18), K_SH_F8,
SL_KEY_F(19), K_SH_F9,
SL_KEY_F(20), K_SH_F10,
SL_KEY_F(21), K_CTRL_F1,
SL_KEY_F(22), K_CTRL_F2,
SL_KEY_F(23), K_CTRL_F3,
SL_KEY_F(24), K_CTRL_F4,
SL_KEY_F(25), K_CTRL_F5,
SL_KEY_F(26), K_CTRL_F6,
SL_KEY_F(27), K_CTRL_F7,
SL_KEY_F(28), K_CTRL_F8,
SL_KEY_F(29), K_CTRL_F9,
SL_KEY_F(30), K_CTRL_F10,
SL_KEY_F(31), K_ALT_F1,
SL_KEY_F(32), K_ALT_F2,
SL_KEY_F(33), K_ALT_F3,
SL_KEY_F(34), K_ALT_F4,
SL_KEY_F(35), K_ALT_F5,
SL_KEY_F(36), K_ALT_F6,
SL_KEY_F(37), K_ALT_F7,
SL_KEY_F(38), K_ALT_F8,
SL_KEY_F(39), K_ALT_F9,
SL_KEY_F(40), K_ALT_F10
};
/* *********************************************************************** */
/* a table of alt+letter translation */
static int transAltKeyLetterTab[] =
{
'A' , K_ALT_A , 'B' , K_ALT_B , 'C' , K_ALT_C ,
'D' , K_ALT_D , 'E' , K_ALT_E , 'F' , K_ALT_F ,
'G' , K_ALT_G , 'H' , K_ALT_H , 'I' , K_ALT_I ,
'J' , K_ALT_J , 'K' , K_ALT_K , 'L' , K_ALT_L ,
'M' , K_ALT_M , 'N' , K_ALT_N , 'O' , K_ALT_O ,
'P' , K_ALT_P , 'Q' , K_ALT_Q , 'R' , K_ALT_R ,
'S' , K_ALT_S , 'T' , K_ALT_T , 'U' , K_ALT_U ,
'V' , K_ALT_V , 'W' , K_ALT_W , 'X' , K_ALT_X ,
'Y' , K_ALT_Y , 'Z' , K_ALT_Z
};
/* a shortcut only */
#define CTRL_PRESSED CONTROL_PRESSED
/* a table of alt+digit translation */
static int transAltKeyDigitTab[] =
{
'0' , K_ALT_0 , '1' , K_ALT_1 ,
'2' , K_ALT_2 , '3' , K_ALT_3 ,
'4' , K_ALT_4 , '5' , K_ALT_5 ,
'6' , K_ALT_6 , '7' , K_ALT_7 ,
'8' , K_ALT_8 , '9' , K_ALT_9
};
/* *********************************************************************** */
#ifdef IBMPC_SYSTEM
/* a table of Dos ScanCode translation - hard coded in Slang */
static unsigned char transDosScanCodeTab[] =
/* a table of keys translation */
static int KeyTrans[][ 2 ] =
{
'A' , 0x1E , 'B' , 0x30 , 'C' , 0x2E , 'D' , 0x20 , 'E' , 0x12 ,
'F' , 0x21 , 'G' , 0x22 , 'H' , 0x23 , 'I' , 0x17 , 'J' , 0x24 ,
'K' , 0x25 , 'L' , 0x26 , 'M' , 0x32 , 'N' , 0x31 , 'O' , 0x18 ,
'P' , 0x19 , 'Q' , 0x10 , 'R' , 0x13 , 'S' , 0x1F , 'T' , 0x14 ,
'U' , 0x16 , 'V' , 0x2F , 'W' , 0x11 , 'X' , 0x2D , 'Y' , 0x15 ,
'Z' , 0x2C , '1' , 0x78 , '2' , 0x79 , '3' , 0x7A , '4' , 0x7B ,
'5' , 0x7C , '6' , 0x7D , '7' , 0x7E , '8' , 0x7F , '9' , 0x80 ,
'0' , 0x81
};
{ SL_KEY_UP, K_UP },
{ SL_KEY_DOWN, K_DOWN },
{ SL_KEY_LEFT, K_LEFT },
{ SL_KEY_RIGHT, K_RIGHT },
{ SL_KEY_HOME, K_HOME },
{ SL_KEY_END, K_END },
{ SL_KEY_PPAGE, K_PGUP },
{ SL_KEY_NPAGE, K_PGDN },
#if HB_GT_KBD_MODIF_MASK
{ SL_KEY_UP | ( CTRL_PRESSED << 16 ), K_CTRL_UP },
{ SL_KEY_DOWN | ( CTRL_PRESSED << 16 ), K_CTRL_DOWN },
{ SL_KEY_LEFT | ( CTRL_PRESSED << 16 ), K_CTRL_LEFT },
{ SL_KEY_RIGHT | ( CTRL_PRESSED << 16 ), K_CTRL_RIGHT },
{ SL_KEY_HOME | ( CTRL_PRESSED << 16 ), K_CTRL_HOME },
{ SL_KEY_END | ( CTRL_PRESSED << 16 ), K_CTRL_END },
{ SL_KEY_PPAGE | ( CTRL_PRESSED << 16 ), K_CTRL_PGUP },
{ SL_KEY_NPAGE | ( CTRL_PRESSED << 16 ), K_CTRL_PGDN },
{ SL_KEY_UP | ( ALTL_PRESSED << 16 ), K_ALT_UP },
{ SL_KEY_DOWN | ( ALTL_PRESSED << 16 ), K_ALT_DOWN },
{ SL_KEY_LEFT | ( ALTL_PRESSED << 16 ), K_ALT_LEFT },
{ SL_KEY_RIGHT | ( ALTL_PRESSED << 16 ), K_ALT_RIGHT },
{ SL_KEY_HOME | ( ALTL_PRESSED << 16 ), K_ALT_HOME },
{ SL_KEY_END | ( ALTL_PRESSED << 16 ), K_ALT_END },
{ SL_KEY_PPAGE | ( ALTL_PRESSED << 16 ), K_ALT_PGUP },
{ SL_KEY_NPAGE | ( ALTL_PRESSED << 16 ), K_ALT_PGDN },
#endif
{ SL_KEY_IC, K_INS },
{ SL_KEY_ESC, K_ESC },
{ SL_KEY_DELETE, K_DEL },
{ SL_KEY_BACKSPACE, K_BS },
#if HB_GT_KBD_MODIF_MASK
{ SL_KEY_IC | ( CTRL_PRESSED << 16 ), K_CTRL_INS },
/* { SL_KEY_ESC | ( CTRL_PRESSED << 16 ), K_CTRL_ESC }, */
{ SL_KEY_DELETE | ( CTRL_PRESSED << 16 ), K_CTRL_DEL },
{ SL_KEY_BACKSPACE | ( CTRL_PRESSED << 16 ), K_CTRL_BS },
/*
{ K_TAB | ( CTRL_PRESSED << 16 ), K_CTRL_TAB },
??????????????? K_CTRL_PRTSCR,
??????????????? K_CTRL_QUESTION,
*/
{ SL_KEY_IC | ( ALTL_PRESSED << 16 ), K_ALT_INS },
{ SL_KEY_ESC | ( ALTL_PRESSED << 16 ), K_ALT_ESC },
{ SL_KEY_DELETE | ( ALTL_PRESSED << 16 ), K_ALT_DEL },
{ SL_KEY_BACKSPACE | ( ALTL_PRESSED << 16 ), K_ALT_BS },
{ K_TAB | ( ALTL_PRESSED << 16 ), K_ALT_TAB },
/* ??????????????? K_ALT_EQUALS, */
{ '/' | ( CTRL_PRESSED << 16 ), KP_CTRL_SLASH},
{ '*' | ( CTRL_PRESSED << 16 ), KP_CTRL_ASTERISK},
{ '-' | ( CTRL_PRESSED << 16 ), KP_CTRL_MINUS},
{ '+' | ( CTRL_PRESSED << 16 ), KP_CTRL_PLUS },
{ K_ENTER | ( CTRL_PRESSED << 16 ), K_CTRL_ENTER },
{ SL_KEY_NUM_5 | ( CTRL_PRESSED << 16 ), KP_CTRL_5 },
{ '/' | ( ALTL_PRESSED << 16 ), KP_ALT_SLASH },
{ '*' | ( ALTL_PRESSED << 16 ), KP_ALT_ASTERISK},
{ '-' | ( ALTL_PRESSED << 16 ), KP_ALT_MINUS },
{ '+' | ( ALTL_PRESSED << 16 ), KP_ALT_PLUS },
{ K_ENTER | ( ALTL_PRESSED << 16 ), K_ALT_ENTER },
{ K_ENTER | ( ALTR_PRESSED << 16 ), K_ALT_ENTER },
{ SL_KEY_NUM_5 | ( ALTL_PRESSED << 16 ), KP_ALT_5 },
{ SL_KEY_NUM_5 | ( ALTR_PRESSED << 16 ), KP_ALT_5 },
{ SL_KEY_B2 | ( ALTR_PRESSED << 16 ), KP_ALT_5 },
{ K_TAB | ( SHIFT_PRESSED << 16 ), K_SH_TAB },
#endif
{ SL_KEY_F(1), K_F1 },
{ SL_KEY_F(2), K_F2 },
{ SL_KEY_F(3), K_F3 },
{ SL_KEY_F(4), K_F4 },
{ SL_KEY_F(5), K_F5 },
{ SL_KEY_F(6), K_F6 },
{ SL_KEY_F(7), K_F7 },
{ SL_KEY_F(8), K_F8 },
{ SL_KEY_F(9), K_F9 },
{ SL_KEY_F(10), K_F10 },
{ SL_KEY_F(11), K_SH_F1 },
{ SL_KEY_F(12), K_SH_F2 },
{ SL_KEY_F(13), K_SH_F3 },
{ SL_KEY_F(14), K_SH_F4 },
{ SL_KEY_F(15), K_SH_F5 },
{ SL_KEY_F(16), K_SH_F6 },
{ SL_KEY_F(17), K_SH_F7 },
{ SL_KEY_F(18), K_SH_F8 },
{ SL_KEY_F(19), K_SH_F9 },
{ SL_KEY_F(20), K_SH_F10 },
{ SL_KEY_F(21), K_CTRL_F1 },
{ SL_KEY_F(22), K_CTRL_F2 },
{ SL_KEY_F(23), K_CTRL_F3 },
{ SL_KEY_F(24), K_CTRL_F4 },
{ SL_KEY_F(25), K_CTRL_F5 },
{ SL_KEY_F(26), K_CTRL_F6 },
{ SL_KEY_F(27), K_CTRL_F7 },
{ SL_KEY_F(28), K_CTRL_F8 },
{ SL_KEY_F(29), K_CTRL_F9 },
{ SL_KEY_F(30), K_CTRL_F10 },
{ SL_KEY_F(31), K_ALT_F1 },
{ SL_KEY_F(32), K_ALT_F2 },
{ SL_KEY_F(33), K_ALT_F3 },
{ SL_KEY_F(34), K_ALT_F4 },
{ SL_KEY_F(35), K_ALT_F5 },
{ SL_KEY_F(36), K_ALT_F6 },
{ SL_KEY_F(37), K_ALT_F7 },
{ SL_KEY_F(38), K_ALT_F8 },
{ SL_KEY_F(39), K_ALT_F9 },
{ SL_KEY_F(40), K_ALT_F10 },
#if HB_GT_KBD_MODIF_MASK
#ifdef __linux__
{ SL_KEY_ALT( 'A' ) | ( ALTL_PRESSED << 16 ), K_ALT_A },
{ SL_KEY_ALT( 'B' ) | ( ALTL_PRESSED << 16 ), K_ALT_B },
{ SL_KEY_ALT( 'C' ) | ( ALTL_PRESSED << 16 ), K_ALT_C },
{ SL_KEY_ALT( 'D' ) | ( ALTL_PRESSED << 16 ), K_ALT_D },
{ SL_KEY_ALT( 'E' ) | ( ALTL_PRESSED << 16 ), K_ALT_E },
{ SL_KEY_ALT( 'F' ) | ( ALTL_PRESSED << 16 ), K_ALT_F },
{ SL_KEY_ALT( 'G' ) | ( ALTL_PRESSED << 16 ), K_ALT_G },
{ SL_KEY_ALT( 'H' ) | ( ALTL_PRESSED << 16 ), K_ALT_H },
{ SL_KEY_ALT( 'I' ) | ( ALTL_PRESSED << 16 ), K_ALT_I },
{ SL_KEY_ALT( 'J' ) | ( ALTL_PRESSED << 16 ), K_ALT_J },
{ SL_KEY_ALT( 'K' ) | ( ALTL_PRESSED << 16 ), K_ALT_K },
{ SL_KEY_ALT( 'L' ) | ( ALTL_PRESSED << 16 ), K_ALT_L },
{ SL_KEY_ALT( 'M' ) | ( ALTL_PRESSED << 16 ), K_ALT_M },
{ SL_KEY_ALT( 'N' ) | ( ALTL_PRESSED << 16 ), K_ALT_N },
{ SL_KEY_ALT( 'O' ) | ( ALTL_PRESSED << 16 ), K_ALT_O },
{ SL_KEY_ALT( 'P' ) | ( ALTL_PRESSED << 16 ), K_ALT_P },
{ SL_KEY_ALT( 'Q' ) | ( ALTL_PRESSED << 16 ), K_ALT_Q },
{ SL_KEY_ALT( 'R' ) | ( ALTL_PRESSED << 16 ), K_ALT_R },
{ SL_KEY_ALT( 'S' ) | ( ALTL_PRESSED << 16 ), K_ALT_S },
{ SL_KEY_ALT( 'T' ) | ( ALTL_PRESSED << 16 ), K_ALT_T },
{ SL_KEY_ALT( 'U' ) | ( ALTL_PRESSED << 16 ), K_ALT_U },
{ SL_KEY_ALT( 'V' ) | ( ALTL_PRESSED << 16 ), K_ALT_V },
{ SL_KEY_ALT( 'W' ) | ( ALTL_PRESSED << 16 ), K_ALT_W },
{ SL_KEY_ALT( 'X' ) | ( ALTL_PRESSED << 16 ), K_ALT_X },
{ SL_KEY_ALT( 'Y' ) | ( ALTL_PRESSED << 16 ), K_ALT_Y },
{ SL_KEY_ALT( 'Z' ) | ( ALTL_PRESSED << 16 ), K_ALT_Z },
{ SL_KEY_ALT( 'a' ) | ( ALTL_PRESSED << 16 ), K_ALT_A },
{ SL_KEY_ALT( 'b' ) | ( ALTL_PRESSED << 16 ), K_ALT_B },
{ SL_KEY_ALT( 'c' ) | ( ALTL_PRESSED << 16 ), K_ALT_C },
{ SL_KEY_ALT( 'd' ) | ( ALTL_PRESSED << 16 ), K_ALT_D },
{ SL_KEY_ALT( 'e' ) | ( ALTL_PRESSED << 16 ), K_ALT_E },
{ SL_KEY_ALT( 'f' ) | ( ALTL_PRESSED << 16 ), K_ALT_F },
{ SL_KEY_ALT( 'g' ) | ( ALTL_PRESSED << 16 ), K_ALT_G },
{ SL_KEY_ALT( 'h' ) | ( ALTL_PRESSED << 16 ), K_ALT_H },
{ SL_KEY_ALT( 'i' ) | ( ALTL_PRESSED << 16 ), K_ALT_I },
{ SL_KEY_ALT( 'j' ) | ( ALTL_PRESSED << 16 ), K_ALT_J },
{ SL_KEY_ALT( 'k' ) | ( ALTL_PRESSED << 16 ), K_ALT_K },
{ SL_KEY_ALT( 'l' ) | ( ALTL_PRESSED << 16 ), K_ALT_L },
{ SL_KEY_ALT( 'm' ) | ( ALTL_PRESSED << 16 ), K_ALT_M },
{ SL_KEY_ALT( 'n' ) | ( ALTL_PRESSED << 16 ), K_ALT_N },
{ SL_KEY_ALT( 'o' ) | ( ALTL_PRESSED << 16 ), K_ALT_O },
{ SL_KEY_ALT( 'p' ) | ( ALTL_PRESSED << 16 ), K_ALT_P },
{ SL_KEY_ALT( 'q' ) | ( ALTL_PRESSED << 16 ), K_ALT_Q },
{ SL_KEY_ALT( 'r' ) | ( ALTL_PRESSED << 16 ), K_ALT_R },
{ SL_KEY_ALT( 's' ) | ( ALTL_PRESSED << 16 ), K_ALT_S },
{ SL_KEY_ALT( 't' ) | ( ALTL_PRESSED << 16 ), K_ALT_T },
{ SL_KEY_ALT( 'u' ) | ( ALTL_PRESSED << 16 ), K_ALT_U },
{ SL_KEY_ALT( 'v' ) | ( ALTL_PRESSED << 16 ), K_ALT_V },
{ SL_KEY_ALT( 'w' ) | ( ALTL_PRESSED << 16 ), K_ALT_W },
{ SL_KEY_ALT( 'x' ) | ( ALTL_PRESSED << 16 ), K_ALT_X },
{ SL_KEY_ALT( 'y' ) | ( ALTL_PRESSED << 16 ), K_ALT_Y },
{ SL_KEY_ALT( 'z' ) | ( ALTL_PRESSED << 16 ), K_ALT_Z },
{ SL_KEY_ALT( '0' ) | ( ALTL_PRESSED << 16 ), K_ALT_0 },
{ SL_KEY_ALT( '1' ) | ( ALTL_PRESSED << 16 ), K_ALT_1 },
{ SL_KEY_ALT( '2' ) | ( ALTL_PRESSED << 16 ), K_ALT_2 },
{ SL_KEY_ALT( '3' ) | ( ALTL_PRESSED << 16 ), K_ALT_3 },
{ SL_KEY_ALT( '4' ) | ( ALTL_PRESSED << 16 ), K_ALT_4 },
{ SL_KEY_ALT( '5' ) | ( ALTL_PRESSED << 16 ), K_ALT_5 },
{ SL_KEY_ALT( '6' ) | ( ALTL_PRESSED << 16 ), K_ALT_6 },
{ SL_KEY_ALT( '7' ) | ( ALTL_PRESSED << 16 ), K_ALT_7 },
{ SL_KEY_ALT( '8' ) | ( ALTL_PRESSED << 16 ), K_ALT_8 },
{ SL_KEY_ALT( '9' ) | ( ALTL_PRESSED << 16 ), K_ALT_9 },
#else
{ 'A' | ( ALTL_PRESSED << 16 ), K_ALT_A },
{ 'B' | ( ALTL_PRESSED << 16 ), K_ALT_B },
{ 'C' | ( ALTL_PRESSED << 16 ), K_ALT_C },
{ 'D' | ( ALTL_PRESSED << 16 ), K_ALT_D },
{ 'E' | ( ALTL_PRESSED << 16 ), K_ALT_E },
{ 'F' | ( ALTL_PRESSED << 16 ), K_ALT_F },
{ 'G' | ( ALTL_PRESSED << 16 ), K_ALT_G },
{ 'H' | ( ALTL_PRESSED << 16 ), K_ALT_H },
{ 'I' | ( ALTL_PRESSED << 16 ), K_ALT_I },
{ 'J' | ( ALTL_PRESSED << 16 ), K_ALT_J },
{ 'K' | ( ALTL_PRESSED << 16 ), K_ALT_K },
{ 'L' | ( ALTL_PRESSED << 16 ), K_ALT_L },
{ 'M' | ( ALTL_PRESSED << 16 ), K_ALT_M },
{ 'N' | ( ALTL_PRESSED << 16 ), K_ALT_N },
{ 'O' | ( ALTL_PRESSED << 16 ), K_ALT_O },
{ 'P' | ( ALTL_PRESSED << 16 ), K_ALT_P },
{ 'Q' | ( ALTL_PRESSED << 16 ), K_ALT_Q },
{ 'R' | ( ALTL_PRESSED << 16 ), K_ALT_R },
{ 'S' | ( ALTL_PRESSED << 16 ), K_ALT_S },
{ 'T' | ( ALTL_PRESSED << 16 ), K_ALT_T },
{ 'U' | ( ALTL_PRESSED << 16 ), K_ALT_U },
{ 'V' | ( ALTL_PRESSED << 16 ), K_ALT_V },
{ 'W' | ( ALTL_PRESSED << 16 ), K_ALT_W },
{ 'X' | ( ALTL_PRESSED << 16 ), K_ALT_X },
{ 'Y' | ( ALTL_PRESSED << 16 ), K_ALT_Y },
{ 'Z' | ( ALTL_PRESSED << 16 ), K_ALT_Z },
{ 'a' | ( ALTL_PRESSED << 16 ), K_ALT_A },
{ 'b' | ( ALTL_PRESSED << 16 ), K_ALT_B },
{ 'c' | ( ALTL_PRESSED << 16 ), K_ALT_C },
{ 'd' | ( ALTL_PRESSED << 16 ), K_ALT_D },
{ 'e' | ( ALTL_PRESSED << 16 ), K_ALT_E },
{ 'f' | ( ALTL_PRESSED << 16 ), K_ALT_F },
{ 'g' | ( ALTL_PRESSED << 16 ), K_ALT_G },
{ 'h' | ( ALTL_PRESSED << 16 ), K_ALT_H },
{ 'i' | ( ALTL_PRESSED << 16 ), K_ALT_I },
{ 'j' | ( ALTL_PRESSED << 16 ), K_ALT_J },
{ 'k' | ( ALTL_PRESSED << 16 ), K_ALT_K },
{ 'l' | ( ALTL_PRESSED << 16 ), K_ALT_L },
{ 'm' | ( ALTL_PRESSED << 16 ), K_ALT_M },
{ 'n' | ( ALTL_PRESSED << 16 ), K_ALT_N },
{ 'o' | ( ALTL_PRESSED << 16 ), K_ALT_O },
{ 'p' | ( ALTL_PRESSED << 16 ), K_ALT_P },
{ 'q' | ( ALTL_PRESSED << 16 ), K_ALT_Q },
{ 'r' | ( ALTL_PRESSED << 16 ), K_ALT_R },
{ 's' | ( ALTL_PRESSED << 16 ), K_ALT_S },
{ 't' | ( ALTL_PRESSED << 16 ), K_ALT_T },
{ 'u' | ( ALTL_PRESSED << 16 ), K_ALT_U },
{ 'v' | ( ALTL_PRESSED << 16 ), K_ALT_V },
{ 'w' | ( ALTL_PRESSED << 16 ), K_ALT_W },
{ 'x' | ( ALTL_PRESSED << 16 ), K_ALT_X },
{ 'y' | ( ALTL_PRESSED << 16 ), K_ALT_Y },
{ 'z' | ( ALTL_PRESSED << 16 ), K_ALT_Z },
{ '0' | ( ALTL_PRESSED << 16 ), K_ALT_0 },
{ '1' | ( ALTL_PRESSED << 16 ), K_ALT_1 },
{ '2' | ( ALTL_PRESSED << 16 ), K_ALT_2 },
{ '3' | ( ALTL_PRESSED << 16 ), K_ALT_3 },
{ '4' | ( ALTL_PRESSED << 16 ), K_ALT_4 },
{ '5' | ( ALTL_PRESSED << 16 ), K_ALT_5 },
{ '6' | ( ALTL_PRESSED << 16 ), K_ALT_6 },
{ '7' | ( ALTL_PRESSED << 16 ), K_ALT_7 },
{ '8' | ( ALTL_PRESSED << 16 ), K_ALT_8 },
{ '9' | ( ALTL_PRESSED << 16 ), K_ALT_9 },
#endif
#endif
{ SL_KEY_ALT( 'A' ), K_ALT_A },
{ SL_KEY_ALT( 'B' ), K_ALT_B },
{ SL_KEY_ALT( 'C' ), K_ALT_C },
{ SL_KEY_ALT( 'D' ), K_ALT_D },
{ SL_KEY_ALT( 'E' ), K_ALT_E },
{ SL_KEY_ALT( 'F' ), K_ALT_F },
{ SL_KEY_ALT( 'G' ), K_ALT_G },
{ SL_KEY_ALT( 'H' ), K_ALT_H },
{ SL_KEY_ALT( 'I' ), K_ALT_I },
{ SL_KEY_ALT( 'J' ), K_ALT_J },
{ SL_KEY_ALT( 'K' ), K_ALT_K },
{ SL_KEY_ALT( 'L' ), K_ALT_L },
{ SL_KEY_ALT( 'M' ), K_ALT_M },
{ SL_KEY_ALT( 'N' ), K_ALT_N },
{ SL_KEY_ALT( 'O' ), K_ALT_O },
{ SL_KEY_ALT( 'P' ), K_ALT_P },
{ SL_KEY_ALT( 'Q' ), K_ALT_Q },
{ SL_KEY_ALT( 'R' ), K_ALT_R },
{ SL_KEY_ALT( 'S' ), K_ALT_S },
{ SL_KEY_ALT( 'T' ), K_ALT_T },
{ SL_KEY_ALT( 'U' ), K_ALT_U },
{ SL_KEY_ALT( 'V' ), K_ALT_V },
{ SL_KEY_ALT( 'W' ), K_ALT_W },
{ SL_KEY_ALT( 'X' ), K_ALT_X },
{ SL_KEY_ALT( 'Y' ), K_ALT_Y },
{ SL_KEY_ALT( 'Z' ), K_ALT_Z },
{ SL_KEY_ALT( 'a' ), K_ALT_A },
{ SL_KEY_ALT( 'b' ), K_ALT_B },
{ SL_KEY_ALT( 'c' ), K_ALT_C },
{ SL_KEY_ALT( 'd' ), K_ALT_D },
{ SL_KEY_ALT( 'e' ), K_ALT_E },
{ SL_KEY_ALT( 'f' ), K_ALT_F },
{ SL_KEY_ALT( 'g' ), K_ALT_G },
{ SL_KEY_ALT( 'h' ), K_ALT_H },
{ SL_KEY_ALT( 'i' ), K_ALT_I },
{ SL_KEY_ALT( 'j' ), K_ALT_J },
{ SL_KEY_ALT( 'k' ), K_ALT_K },
{ SL_KEY_ALT( 'l' ), K_ALT_L },
{ SL_KEY_ALT( 'm' ), K_ALT_M },
{ SL_KEY_ALT( 'n' ), K_ALT_N },
{ SL_KEY_ALT( 'o' ), K_ALT_O },
{ SL_KEY_ALT( 'p' ), K_ALT_P },
{ SL_KEY_ALT( 'q' ), K_ALT_Q },
{ SL_KEY_ALT( 'r' ), K_ALT_R },
{ SL_KEY_ALT( 's' ), K_ALT_S },
{ SL_KEY_ALT( 't' ), K_ALT_T },
{ SL_KEY_ALT( 'u' ), K_ALT_U },
{ SL_KEY_ALT( 'v' ), K_ALT_V },
{ SL_KEY_ALT( 'w' ), K_ALT_W },
{ SL_KEY_ALT( 'x' ), K_ALT_X },
{ SL_KEY_ALT( 'y' ), K_ALT_Y },
{ SL_KEY_ALT( 'z' ), K_ALT_Z },
{ SL_KEY_ALT( '0' ), K_ALT_0 },
{ SL_KEY_ALT( '1' ), K_ALT_1 },
{ SL_KEY_ALT( '2' ), K_ALT_2 },
{ SL_KEY_ALT( '3' ), K_ALT_3 },
{ SL_KEY_ALT( '4' ), K_ALT_4 },
{ SL_KEY_ALT( '5' ), K_ALT_5 },
{ SL_KEY_ALT( '6' ), K_ALT_6 },
{ SL_KEY_ALT( '7' ), K_ALT_7 },
{ SL_KEY_ALT( '8' ), K_ALT_8 },
{ SL_KEY_ALT( '9' ), K_ALT_9 }
};
/* *********************************************************************** */
#define KeyTransSize ( sizeof( KeyTrans ) / ( 2 * sizeof ( int ) ) )
static void hb_gt_SortKeyTrans( void )
{
int i, j, min, KeyTmp[ 2 ];
for ( i = 0; i < ( KeyTransSize - 1 ); i++ )
{
min = i;
for ( j = i + 1; j < KeyTransSize; j++ )
{
if ( KeyTrans[ j ][ 0 ] < KeyTrans[ min ][ 0 ] )
min = j;
}
if ( min > i )
{
KeyTmp[ 0 ] = KeyTrans[ i ][ 0 ];
KeyTmp[ 1 ] = KeyTrans[ i ][ 1 ];
KeyTrans[ i ][ 0 ] = KeyTrans[ min ][ 0 ];
KeyTrans[ i ][ 1 ] = KeyTrans[ min ][ 1 ];
KeyTrans[ min ][ 0 ] = KeyTmp[ 0 ];
KeyTrans[ min ][ 1 ] = KeyTmp[ 1 ];
}
}
/*
for ( i = 0; i < KeyTransSize; i++ )
fprintf( stderr, "%02x %8x %8x\n", i, KeyTrans[ i ][ 0 ], KeyTrans[ i ][ 1 ] );
*/
}
/* ************************************************************************* */
/* standard binary search */
static int hb_gt_FindKeyTrans( int SlangKey )
{
int Start,Stop,CurPos;
if ( ( SlangKey >= KeyTrans[ 0 ][ 0 ] ) &&
( SlangKey <= KeyTrans[ KeyTransSize - 1 ][ 0 ] ) )
{
Start = 0; Stop = KeyTransSize - 1;
while( Start <= Stop )
{
CurPos = ( Start + Stop ) / 2;
/* fprintf( stderr, "%d %d %d\n", i, KeyTrans[ i ][ 0 ], KeyTrans[ i ][ 1 ] ); */
if( SlangKey == KeyTrans[ CurPos ][ 0 ] )
return( KeyTrans[ CurPos ][ 1 ] );
else if( SlangKey < KeyTrans[ CurPos ][ 0 ] )
Stop = CurPos - 1;
else if( SlangKey > KeyTrans[ CurPos ][ 0 ] )
Start = CurPos + 1;
}
}
/* return( SlangKey ); */
return( 0 );
}
/* ************************************************************************* */
int hb_gt_SetKeyTrans( int SlangKey, int ClipKey )
{
int i;
if ( ( SlangKey >= KeyTrans[ 0 ][ 0 ] ) &&
( SlangKey <= KeyTrans[ KeyTransSize - 1 ][ 0 ] ) )
{
for ( i = 0; i < KeyTransSize; i++ )
{
if ( SlangKey == KeyTrans[ i ][ 0 ] )
KeyTrans[ i ][ 1 ] = ClipKey;
}
}
return( i < KeyTransSize );
}
/* ************************************************************************* */