1119 lines
34 KiB
C
1119 lines
34 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Video subsystem based on Slang screen library.
|
|
*
|
|
* Copyright 2000 Marek Paliwoda <paliwoda@inetia.pl>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version, with one exception:
|
|
*
|
|
* The exception is that if you link the Harbour Runtime Library (HRL)
|
|
* and/or the Harbour Virtual Machine (HVM) with other files to produce
|
|
* an executable, this does not by itself cause the resulting executable
|
|
* to be covered by the GNU General Public License. Your use of that
|
|
* executable is in no way restricted on account of linking the HRL
|
|
* and/or HVM code into it.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
|
|
* their web site at http://www.gnu.org/).
|
|
*
|
|
*/
|
|
|
|
/* 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 can not work ! */
|
|
#if SLANG_VERSION < 10400
|
|
typedef unsigned short SLsmg_Char_Type;
|
|
#define SLSMG_EXTRACT_CHAR( x ) ( ( x ) & 0xFF )
|
|
#define SLSMG_EXTRACT_COLOR( x ) ( ( ( x ) >> 8 ) & 0xFF )
|
|
#define SLSMG_BUILD_CHAR( ch, color ) ( ( ( SLsmg_Char_Type ) ( unsigned char )( ch ) ) | ( ( color ) << 8 ) )
|
|
#define SLSMG_BOARD_CHAR 'h'
|
|
#define SLSMG_BLOCK_CHAR '0'
|
|
#endif
|
|
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
|
|
#include "hbapigt.h"
|
|
#include "inkey.ch"
|
|
|
|
/* *********************************************************************** */
|
|
|
|
/* if we can not manipulate cursor state */
|
|
#define SC_UNAVAIL -1
|
|
|
|
/* Slang reserves color 0 and 1 as a normal
|
|
and reverse color so we can't use them
|
|
*/
|
|
#define SLANG_RESERVED_COLORS 2
|
|
|
|
/* 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();
|
|
|
|
/* 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, nation and control chars) */
|
|
static SLsmg_Char_Type s_convHighChars[ 256 ];
|
|
/* bit indication if char is a nation char - assumes char is 8-bit */
|
|
static unsigned char s_IsNationChar[ 128 / 8 ];
|
|
|
|
/* to convert colors to Clipper mode */
|
|
static char * s_colorNames[] =
|
|
{
|
|
"black" ,
|
|
"blue" ,
|
|
"green" ,
|
|
"cyan" ,
|
|
"red" ,
|
|
"magenta" ,
|
|
"brown" ,
|
|
"lightgray" ,
|
|
"gray" ,
|
|
"brightblue" ,
|
|
"brightgreen" ,
|
|
"brightcyan" ,
|
|
"brightred" ,
|
|
"brightmagenta",
|
|
"yellow" ,
|
|
"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;
|
|
/* window's resize handler */
|
|
static void sigwinch_handler( int sig )
|
|
{
|
|
hb_gt_sln_bScreen_Size_Changed = TRUE;
|
|
SLsignal( SIGWINCH, sigwinch_handler );
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
/* I think this function should not be void. It should be BOOL */
|
|
void hb_gt_Init( int iFilenoStdin, int iFilenoStdout, int iFilenoStderr )
|
|
{
|
|
BOOL gt_Inited = FALSE;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Init()"));
|
|
|
|
s_uiDispCount = 0;
|
|
|
|
/* read a terminal descripion from a terminfo database */
|
|
SLtt_get_terminfo();
|
|
/* initialize higher-level Slang routines */
|
|
if( SLkp_init() != -1 )
|
|
{
|
|
/* initialize a terminal stuff and a Slang
|
|
keyboard subsystem for the first time */
|
|
if( hb_gt_Init_Terminal( 0 ) )
|
|
{
|
|
/* initialize a screen handling subsytem */
|
|
if( SLsmg_init_smg() != -1 )
|
|
{
|
|
/* install window resize handler */
|
|
SLsignal( SIGWINCH, sigwinch_handler );
|
|
|
|
/* do not indicate USER_BREAK in SLang_Error - ??? */
|
|
SLang_Ignore_User_Abort = 1;
|
|
|
|
/* no default abort procesing */
|
|
SLang_set_abort_signal( NULL );
|
|
|
|
/* 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
|
|
*/
|
|
/* turn on a cursor visibility */
|
|
if( SLtt_set_cursor_visibility( 1 ) == -1 )
|
|
s_sCursorStyle = SC_UNAVAIL;
|
|
|
|
/* an uncertain way to check if we run under linux console */
|
|
s_linuxConsole = ( strncmp( getenv( "TERM" ), "linux", 5 ) == 0 );
|
|
/* an uncertain way to check if we run under xterm */
|
|
s_underXTerm = ( strstr( getenv( "TERM" ), "xterm" ) != NULL );
|
|
|
|
/* 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. */
|
|
SLtt_Blink_Mode = 0;
|
|
SLtt_Use_Blink_For_ACS = 0;
|
|
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 */
|
|
SLsmg_cls();
|
|
#endif
|
|
/* SLsmg_set_color( 7 ); */
|
|
SLsmg_gotorc( 0, 0 );
|
|
SLsmg_refresh();
|
|
gt_Inited = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
hb_mouse_Init();
|
|
|
|
if( ! gt_Inited )
|
|
{
|
|
char *errmsg = '\r'+'\n'+"Internal error : screen driver initialization failure"+'\r'+'\n'+( char )0;
|
|
/* something went wrong - restore default settings */
|
|
SLang_reset_tty();
|
|
/* 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()"));
|
|
|
|
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 );
|
|
|
|
SLsmg_refresh();
|
|
SLsmg_reset_smg();
|
|
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;
|
|
USHORT row = SLsmg_get_row();
|
|
USHORT col = SLsmg_get_column();
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_AdjustPos(%s, %lu)", pStr, ulLen ));
|
|
|
|
for( ulCount = 0; ulCount < ulLen; ulCount++ )
|
|
{
|
|
switch( *pStr++ )
|
|
{
|
|
case HB_CHAR_BEL:
|
|
break;
|
|
|
|
case HB_CHAR_BS:
|
|
if( col )
|
|
col--;
|
|
else
|
|
{
|
|
col = SLtt_Screen_Cols - 1;
|
|
if( row )
|
|
row--;
|
|
}
|
|
break;
|
|
|
|
case HB_CHAR_LF:
|
|
col = 0;
|
|
/* 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++;
|
|
break;
|
|
|
|
case HB_CHAR_CR:
|
|
col = 0;
|
|
break;
|
|
|
|
default:
|
|
if( col < SLtt_Screen_Cols - 1 )
|
|
col++;
|
|
else
|
|
{
|
|
col = 0;
|
|
if( row < SLtt_Screen_Rows - 1 )
|
|
row++;
|
|
}
|
|
}
|
|
}
|
|
|
|
hb_gt_SetPos( row, col, HB_GT_SET_POS_AFTER );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
USHORT hb_gt_GetCursorStyle( void )
|
|
{
|
|
/* TODO: What shape is the cursor? */
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetCursorStyle()"));
|
|
|
|
/* if we don't know a cursor state - assume visible */
|
|
if( s_sCursorStyle == SC_UNAVAIL )
|
|
return( SC_NORMAL );
|
|
|
|
return( s_sCursorStyle );
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
void hb_gt_SetCursorStyle( USHORT uiStyle )
|
|
{
|
|
/* keyseq to define cursor shape under linux console */
|
|
static char cursDefseq[] = { 27, '[', '?', '1', 'c', 0 };
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetCursorStyle(%hu)", uiStyle));
|
|
|
|
/* TODO: How to set the shape of the cursor ? */
|
|
/* see ..\..\..\tests\working\cursrtst.prg for an explanation */
|
|
if( s_sCursorStyle == SC_UNAVAIL )
|
|
return;
|
|
|
|
if( ( s_sCursorStyle >= SC_NONE ) && ( s_sCursorStyle <= SC_SPECIAL2 ) )
|
|
{
|
|
s_sCursorStyle = uiStyle;
|
|
SLtt_set_cursor_visibility( s_sCursorStyle != SC_NONE );
|
|
|
|
#ifdef __linux__
|
|
/* NOTE: cursor apearence works only under linux console */
|
|
if( s_linuxConsole )
|
|
{
|
|
switch( uiStyle )
|
|
{
|
|
case SC_NONE:
|
|
cursDefseq[ 3 ] = '1';
|
|
break;
|
|
|
|
case SC_NORMAL:
|
|
cursDefseq[ 3 ] = '2';
|
|
break;
|
|
|
|
case SC_INSERT:
|
|
cursDefseq[ 3 ] = '4';
|
|
break;
|
|
|
|
case SC_SPECIAL1:
|
|
cursDefseq[ 3 ] = '8';
|
|
break;
|
|
|
|
case SC_SPECIAL2:
|
|
/* TODO: find a proper sequqnce to set a cursor
|
|
to SC_SPECIAL2 under Linux console */
|
|
cursDefseq[ 3 ] = '4';
|
|
break;
|
|
}
|
|
|
|
SLtt_write_string( cursDefseq );
|
|
|
|
if( s_uiDispCount == 0 )
|
|
SLsmg_refresh();
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
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));
|
|
|
|
Pos = ( unsigned char ) ( ( byChar & 0x7F ) >> 3 );
|
|
Mask = ( unsigned char ) ( 1 << ( byChar & 0x07 ) );
|
|
|
|
/* this hack turns on Normal Char Set when we should draw a 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));
|
|
|
|
pScr = ( SLsmg_Char_Type * ) hb_xgrab( ( ulLen + 1 ) * sizeof( SLsmg_Char_Type ) );
|
|
|
|
for( i = 0; i < ulLen; i++ )
|
|
{
|
|
/* next char to process */
|
|
byChar = *pbyStr++;
|
|
|
|
Pos = ( unsigned char ) ( ( byChar & 0x7F ) >> 3 );
|
|
Mask = ( unsigned char ) ( 1 << ( byChar & 0x07 ) );
|
|
|
|
/* this hack turns on Normal Char Set when we should draw a 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;
|
|
}
|
|
|
|
SLsmg_gotorc( uiRow, uiCol );
|
|
|
|
if( ulLen > 0 )
|
|
SLsmg_write_raw( pScr, ulLen );
|
|
|
|
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;
|
|
USHORT usSavRow = SLsmg_get_row();
|
|
USHORT usSavCol = SLsmg_get_column();
|
|
SLsmg_Char_Type * pBuf = ( SLsmg_Char_Type * ) pbyDst;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetText(%hu, %hu, %hu, %hu, %p)", uiTop, uiLeft, uiBottom, uiRight, pbyDst));
|
|
|
|
Cols = uiRight - uiLeft + 1;
|
|
while( uiTop <= uiBottom )
|
|
{
|
|
SLsmg_gotorc( uiTop, uiLeft );
|
|
SLsmg_read_raw( pBuf, Cols );
|
|
pBuf += Cols;
|
|
++uiTop;
|
|
}
|
|
SLsmg_gotorc( usSavRow, usSavCol );
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
void hb_gt_PutText( USHORT uiTop, USHORT uiLeft, USHORT uiBottom, USHORT uiRight, BYTE * pbySrc )
|
|
{
|
|
int Cols;
|
|
USHORT usSavRow = SLsmg_get_row();
|
|
USHORT usSavCol = SLsmg_get_column();
|
|
SLsmg_Char_Type * pBuf = ( SLsmg_Char_Type * ) pbySrc;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_PutText(%hu, %hu, %hu, %hu, %p)", uiTop, uiLeft, uiBottom, uiRight, pbySrc));
|
|
|
|
Cols = uiRight - uiLeft + 1;
|
|
while( uiTop <= uiBottom )
|
|
{
|
|
SLsmg_gotorc( uiTop, uiLeft );
|
|
SLsmg_write_raw( pBuf, Cols );
|
|
pBuf += Cols;
|
|
++uiTop;
|
|
}
|
|
|
|
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;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetAttribute(%hu, %hu, %hu, %hu, %d)", uiTop, uiLeft, uiBottom, uiRight, (int) byAttr));
|
|
|
|
Rows = uiBottom - uiTop + 1;
|
|
Cols = uiRight - uiLeft + 1;
|
|
|
|
/* note: we are clearing a high bit of color */
|
|
SLsmg_set_color_in_region( ( (int)byAttr + SLANG_RESERVED_COLORS ) & 0x7F,
|
|
uiTop, uiLeft, Rows, Cols );
|
|
|
|
if( s_uiDispCount == 0 )
|
|
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. */
|
|
SHORT usSaveRow, usSaveCol;
|
|
USHORT uiSize;
|
|
|
|
int iLength = ( usRight - usLeft ) + 1;
|
|
int iCount, iColOld, iColNew, iColSize;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Scroll(%hu, %hu, %hu, %hu, %d, %hd, %hd)", uiTop, uiLeft, uiBottom, uiRight, (int) byAttr, iRows, iCols));
|
|
|
|
if( hb_gtRectSize( usTop, usLeft, usBottom, usRight, &uiSize ) == 0 )
|
|
{
|
|
unsigned char * fpBlank = ( unsigned char * ) hb_xgrab( iLength );
|
|
unsigned char * fpBuff = ( unsigned char * ) hb_xgrab( iLength * sizeof( SLsmg_Char_Type ) );
|
|
|
|
memset( fpBlank, ' ', iLength );
|
|
|
|
iColOld = iColNew = usLeft;
|
|
if( iCols >= 0 )
|
|
{
|
|
iColOld += iCols;
|
|
iColSize = ( int ) ( usRight - usLeft );
|
|
iColSize -= iCols;
|
|
}
|
|
else
|
|
{
|
|
iColNew -= iCols;
|
|
iColSize = ( int ) ( usRight - usLeft );
|
|
iColSize += iCols;
|
|
}
|
|
|
|
hb_gtGetPos( &usSaveRow, &usSaveCol );
|
|
|
|
for( iCount = ( iRows >= 0 ? usTop : usBottom );
|
|
( iRows >= 0 ? iCount <= usBottom : iCount >= usTop );
|
|
( iRows >= 0 ? iCount++ : iCount-- ) )
|
|
{
|
|
int iRowPos = iCount + iRows;
|
|
|
|
/* Read the text to be scrolled into the current row */
|
|
if( ( iRows || iCols ) && iRowPos <= usBottom && iRowPos >= usTop )
|
|
hb_gt_GetText( iRowPos, iColOld, iRowPos, iColOld + iColSize, fpBuff );
|
|
|
|
/* Blank the scroll region in the current row */
|
|
hb_gt_Puts( iCount, usLeft, byAttr, fpBlank, iLength );
|
|
|
|
/* Write the scrolled text to the current row */
|
|
if( ( iRows || iCols ) && iRowPos <= usBottom && iRowPos >= usTop )
|
|
hb_gt_PutText( iCount, iColNew, iCount, iColNew + iColSize, fpBuff );
|
|
}
|
|
|
|
hb_xfree( fpBlank );
|
|
hb_xfree( fpBuff );
|
|
|
|
hb_gtSetPos( usSaveRow, usSaveCol );
|
|
/*
|
|
if( s_uiDispCount == 0 )
|
|
SLsmg_refresh();
|
|
*/
|
|
}
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
void hb_gt_DispBegin( void )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispBegin()"));
|
|
|
|
++s_uiDispCount;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
void hb_gt_DispEnd()
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_DispEnd()"));
|
|
|
|
/* 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));
|
|
|
|
HB_SYMBOL_UNUSED( uiRows );
|
|
HB_SYMBOL_UNUSED( uiCols );
|
|
|
|
/* TODO: How to change the size of the screen? */
|
|
return FALSE;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
BOOL hb_gt_GetBlink()
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_GetBlink()"));
|
|
|
|
/* TODO: current implementation disables blinking/intensity */
|
|
return FALSE;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
void hb_gt_SetBlink( BOOL bBlink )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_SetBlink(%d)", (int) bBlink));
|
|
|
|
/* TODO: current implementation disables blinking/intensity */
|
|
HB_SYMBOL_UNUSED( bBlink );
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
void hb_gt_Tone( double dFrequency, double dDuration )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_Tone(%lf, %lf)", dFrequency, dDuration));
|
|
|
|
/* TODO: Implement this */
|
|
|
|
HB_SYMBOL_UNUSED( dFrequency );
|
|
HB_SYMBOL_UNUSED( 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 a 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++ )
|
|
*( pScr + i ) = SLchar;
|
|
|
|
SLsmg_gotorc( uiRow, uiCol );
|
|
|
|
if( ulLen > 0 )
|
|
{
|
|
SLsmg_write_raw( pScr, ulLen );
|
|
|
|
/* 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 )
|
|
{
|
|
USHORT uiRow;
|
|
USHORT uiCol;
|
|
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 )
|
|
{
|
|
USHORT tmp = uiTop;
|
|
uiTop = uiBottom;
|
|
uiBottom = tmp;
|
|
}
|
|
if( uiLeft > uiRight )
|
|
{
|
|
USHORT tmp = uiLeft;
|
|
uiLeft = uiRight;
|
|
uiRight = tmp;
|
|
}
|
|
|
|
uiRow = uiTop;
|
|
uiCol = uiLeft;
|
|
|
|
/* Draw the box or line as specified */
|
|
uiHeight = uiBottom - uiTop + 1;
|
|
uiWidth = uiRight - uiLeft + 1;
|
|
|
|
hb_gt_DispBegin();
|
|
|
|
if( uiHeight > 1 && uiWidth > 1 )
|
|
hb_gt_xPutch( uiRow, uiCol, byAttr, szBox[ 0 ] ); /* Upper left corner */
|
|
|
|
uiCol = ( uiHeight > 1 ? uiLeft + 1 : uiLeft );
|
|
|
|
if( uiCol <= uiRight )
|
|
hb_gt_Replicate( uiRow, uiCol, byAttr, szBox[ 1 ], uiRight - uiLeft + ( uiHeight > 1 ? -1 : 1 ) ); /* Top line */
|
|
|
|
if( uiHeight > 1 && uiWidth > 1 )
|
|
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;
|
|
hb_gt_xPutch( uiRow, uiCol++, byAttr, szBox[ 7 ] ); /* Left side */
|
|
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 )
|
|
{
|
|
hb_gt_xPutch( uiBottom, uiLeft, byAttr, szBox[ 6 ] ); /* Bottom left corner */
|
|
|
|
uiCol = ( uiHeight > 1 ? uiLeft + 1 : uiLeft );
|
|
|
|
if( uiCol <= uiRight && uiHeight > 1 )
|
|
hb_gt_Replicate( uiBottom, uiCol, byAttr, szBox[ 5 ], uiRight - uiLeft + ( uiHeight > 1 ? -1 : 1 ) ); /* Bottom line */
|
|
|
|
hb_gt_xPutch( uiBottom, uiRight, byAttr, szBox[ 4 ] ); /* Bottom right corner */
|
|
}
|
|
|
|
SLsmg_gotorc( uiTop + 1, uiLeft + 1 );
|
|
|
|
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;
|
|
else
|
|
{
|
|
uRow = uiBottom;
|
|
uiBottom = uiTop;
|
|
}
|
|
|
|
/* a box drawing hack */
|
|
s_bUse_Alt_Char_Hack = TRUE;
|
|
|
|
while( uRow <= uiBottom )
|
|
hb_gt_xPutch( uRow++, uiCol, byAttr, byChar );
|
|
|
|
/* 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 ???. */
|
|
|
|
/* *********************************************************************** */
|
|
|
|
BOOL hb_gt_Suspend()
|
|
{
|
|
if( ! s_bSuspended )
|
|
{
|
|
if( SLsmg_suspend_smg() != -1 )
|
|
{
|
|
SLang_reset_tty();
|
|
s_bSuspended = TRUE;
|
|
}
|
|
}
|
|
|
|
return s_bSuspended;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
BOOL hb_gt_Resume()
|
|
{
|
|
if( s_bSuspended &&
|
|
SLsmg_resume_smg() != -1 &&
|
|
hb_gt_Init_Terminal( 1 ) != -1
|
|
) /* reinitialize a terminal */
|
|
SLsmg_refresh();
|
|
|
|
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, 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 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
|
|
*/
|
|
for( i = 0; i < 256 - SLANG_RESERVED_COLORS; i++ )
|
|
{
|
|
fg = ( i & 0x0F );
|
|
bg = ( i >> 4 ) & 0x07; /* bit 7 is a blinking attribute - not used here */
|
|
|
|
/* 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 a conversion chars table */
|
|
for( i = 0; i < 32; i++ )
|
|
/* under Unix control-chars are not visible in a general meaning */
|
|
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;
|
|
|
|
/* init an alternate chars table */
|
|
if( ( p = SLtt_Graphics_Char_Pairs ) )
|
|
{
|
|
len = strlen( p );
|
|
/* 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 ] = 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_DEGREE_CHAR; : s_convHighChars[ ] = SLch; break;
|
|
case SLSMG_PLMINUS_CHAR : s_convHighChars[ ] = SLch; break;
|
|
case SLSMG_BULLET_CHAR : s_convHighChars[ ] = SLch; break;
|
|
*/
|
|
#if SLANG_VERSION > 10400
|
|
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;
|
|
#endif
|
|
case SLSMG_BOARD_CHAR : s_convHighChars[ 178 ] = SLch;
|
|
break;
|
|
case SLSMG_BLOCK_CHAR : s_convHighChars[ 219 ] = SLch;
|
|
break;
|
|
}
|
|
|
|
++p;
|
|
}
|
|
}
|
|
|
|
/* QUESTION: do we have double, single-double, ... frames under xterm ? */
|
|
if( s_underXTerm )
|
|
{
|
|
/* frames of all Clipper type are _B_SINBLE under xterm */
|
|
s_convHighChars[ 205 ] = s_convHighChars[ 196 ];
|
|
s_convHighChars[ 186 ] = s_convHighChars[ 179 ];
|
|
s_convHighChars[ 201 ] = s_convHighChars[ 218 ];
|
|
s_convHighChars[ 214 ] = s_convHighChars[ 218 ];
|
|
s_convHighChars[ 213 ] = s_convHighChars[ 218 ];
|
|
s_convHighChars[ 187 ] = s_convHighChars[ 191 ];
|
|
s_convHighChars[ 183 ] = s_convHighChars[ 191 ];
|
|
s_convHighChars[ 184 ] = s_convHighChars[ 191 ];
|
|
s_convHighChars[ 200 ] = s_convHighChars[ 192 ];
|
|
s_convHighChars[ 211 ] = s_convHighChars[ 192 ];
|
|
s_convHighChars[ 212 ] = s_convHighChars[ 192 ];
|
|
s_convHighChars[ 188 ] = s_convHighChars[ 217 ];
|
|
s_convHighChars[ 189 ] = s_convHighChars[ 217 ];
|
|
s_convHighChars[ 190 ] = s_convHighChars[ 217 ];
|
|
s_convHighChars[ 185 ] = s_convHighChars[ 118 ];
|
|
s_convHighChars[ 204 ] = s_convHighChars[ 195 ];
|
|
s_convHighChars[ 203 ] = s_convHighChars[ 194 ];
|
|
s_convHighChars[ 202 ] = s_convHighChars[ 193 ];
|
|
s_convHighChars[ 206 ] = s_convHighChars[ 197 ];
|
|
}
|
|
|
|
/* 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 );
|
|
*/
|
|
}
|
|
}
|
|
|
|
/* *********************************************************************** */
|