1508 lines
42 KiB
C
1508 lines
42 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Video subsystem for DOS compilers
|
|
*
|
|
* Copyright 1999 {list of individual authors and e-mail addresses}
|
|
* 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, or (at your option)
|
|
* any later version.
|
|
*
|
|
* 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 software; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries 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 Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* The following parts are Copyright of the individual authors.
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* Copyright 1999-2001 Viktor Szakats <viktor.szakats@syenar.hu>
|
|
* hb_gt_CtrlBrkHandler()
|
|
* hb_gt_CtrlBrkRestore()
|
|
*
|
|
* Copyright 1999 David G. Holm <dholm@jsd-llc.com>
|
|
* hb_gt_ReadKey()
|
|
*
|
|
* Copyright 2000 Alejandro de Garate <alex_degarate@hotmail.com>
|
|
* vmode12x40()
|
|
* vmode25x40()
|
|
* vmode28x40()
|
|
* vmode50x40()
|
|
* vmode12x80()
|
|
* vmode25x80()
|
|
* vmode28x80()
|
|
* vmode43x80()
|
|
* vmode50x80()
|
|
* hb_gt_SetMode()
|
|
* hb_gt_GetDisplay()
|
|
*
|
|
* Copyright 1999 Jose Lalin <dezac@corevia.com>
|
|
* Luiz Rafael Culik <Culik@sl.conex.net>
|
|
* Harbour Mouse Subsystem for DOS
|
|
*
|
|
* See doc/license.txt for licensing terms.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This module is based on VIDMGR by Andrew Clarke and modified for
|
|
* the Harbour project
|
|
*/
|
|
|
|
/* NOTE: User programs should never call this layer directly! */
|
|
|
|
#define HB_GT_NAME DOS
|
|
|
|
#include "hbgtcore.h"
|
|
#include "hbinit.h"
|
|
#include "hbapicdp.h"
|
|
#include "hbapiitm.h"
|
|
#include "inkey.ch"
|
|
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <conio.h>
|
|
|
|
|
|
/*
|
|
* use mouse driver save/restore state functions,
|
|
* add other compilers for which calling real mode
|
|
* interrupts with memory pointer is implemented.
|
|
*/
|
|
#if defined(__DJGPP__)
|
|
#define HB_MOUSE_SAVE
|
|
#endif
|
|
|
|
#if defined(__DJGPP__)
|
|
#include <pc.h>
|
|
#include <sys/exceptn.h>
|
|
#include <sys/farptr.h>
|
|
#include <dpmi.h>
|
|
#elif defined(_MSC_VER) || defined(__WATCOMC__)
|
|
#include <signal.h>
|
|
#endif
|
|
|
|
/* For screen support */
|
|
#if defined(__POWERC) || (defined(__TURBOC__) && !defined(__BORLANDC__)) || (defined(__ZTC__) && !defined(__SC__))
|
|
#define FAR far
|
|
#elif defined(HB_OS_DOS) && !defined(__DJGPP__) && !defined(__RSX32__) && !defined(__WATCOMC__)
|
|
#define FAR _far
|
|
#else
|
|
#define FAR
|
|
#endif
|
|
|
|
#if !defined(__DJGPP__)
|
|
#ifndef MK_FP
|
|
#define MK_FP( seg, off ) \
|
|
((void FAR *)(((unsigned long)(seg) << 16)|(unsigned)(off)))
|
|
#endif
|
|
static unsigned char FAR * s_pScreenAddres;
|
|
#endif
|
|
|
|
#if defined(__WATCOMC__) && defined(__386__)
|
|
#define HB_PEEK_BYTE(s,o) ( *( ( UCHAR * ) ( ( (s) << 4 ) | (o) ) ) )
|
|
#define HB_POKE_BYTE(s,o,b) *( ( UCHAR * ) ( ( (s) << 4 ) | (o) ) ) = (b)
|
|
#elif defined(__DJGPP__)
|
|
#define HB_PEEK_BYTE(s,o) _farpeekb( (s), (o) )
|
|
#define HB_POKE_BYTE(s,o,b) _farpokeb( (s), (o), (b) )
|
|
#else
|
|
#define HB_PEEK_BYTE(s,o) ( *( ( UCHAR FAR * ) MK_FP( (s), (o) ) ) )
|
|
#define HB_POKE_BYTE(s,o,b) *( ( UCHAR FAR * ) MK_FP( (s), (o) ) ) = (b)
|
|
#endif
|
|
|
|
static int s_GtId;
|
|
static HB_GT_FUNCS SuperTable;
|
|
#define HB_GTSUPER (&SuperTable)
|
|
#define HB_GTID_PTR (&s_GtId)
|
|
|
|
static int s_iRows;
|
|
static int s_iCols;
|
|
static int s_iCurRow;
|
|
static int s_iCurCol;
|
|
static int s_iCursorStyle;
|
|
static int s_iScreenMode;
|
|
|
|
static BOOL s_bBreak; /* Used to signal Ctrl+Break to hb_inkeyPoll() */
|
|
|
|
static BYTE s_charTransRev[ 256 ];
|
|
static BYTE s_charTrans[ 256 ];
|
|
static BYTE s_keyTrans[ 256 ];
|
|
|
|
#if defined(__RSX32__)
|
|
static int kbhit( void )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.h.ah = 0x0B;
|
|
HB_DOS_INT86( 0x21, ®s, ®s );
|
|
|
|
return regs.HB_XREGS.ax;
|
|
}
|
|
#endif
|
|
|
|
#if !defined(__DJGPP__) && !defined(__RSX32__)
|
|
#if defined(__WATCOMC__) || defined(_MSC_VER)
|
|
static void hb_gt_dos_CtrlBreak_Handler( int iSignal )
|
|
{
|
|
/* Ctrl-Break was pressed */
|
|
/* NOTE: the layout of this function is forced by the compiler
|
|
*/
|
|
HB_SYMBOL_UNUSED( iSignal );
|
|
s_bBreak = TRUE;
|
|
}
|
|
#else
|
|
static int s_iOldCtrlBreak = 0;
|
|
static int hb_gt_dos_CtrlBrkHandler( void )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_CtrlBrkHandler()"));
|
|
s_bBreak = TRUE;
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
static void hb_gt_dos_CtrlBrkRestore( void )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_CtrlBrkRestore()"));
|
|
|
|
#if defined(__WATCOMC__)
|
|
signal( SIGBREAK, SIG_DFL );
|
|
#elif defined(_MSC_VER)
|
|
signal( SIGINT, SIG_DFL );
|
|
#else
|
|
setcbrk( s_iOldCtrlBreak );
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
static int hb_gt_dos_GetScreenMode( void )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetScreenMode()"));
|
|
|
|
#if defined(__WATCOMC__) && defined(__386__)
|
|
return ( int ) *( ( unsigned char * ) 0x0449 );
|
|
#elif defined(__DJGPP__)
|
|
return ( int ) _farpeekb( 0x0040, 0x0049 );
|
|
#else
|
|
return ( int ) *( ( unsigned char FAR * ) MK_FP( 0x0040, 0x0049 ) );
|
|
#endif
|
|
}
|
|
|
|
static void hb_gt_dos_GetScreenSize( int * piRows, int * piCols )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetScreenSize(%p, %p)", piRows, piCols));
|
|
|
|
#if defined(__WATCOMC__) && defined(__386__)
|
|
*piRows = ( int ) *( ( unsigned char * ) 0x0484 ) + 1;
|
|
*piCols = ( int ) *( ( unsigned char * ) 0x044A );
|
|
#elif defined(__DJGPP__)
|
|
*piRows = ( int ) _farpeekb( 0x0040, 0x0084 ) + 1;
|
|
*piCols = ( int ) _farpeekb( 0x0040, 0x004A );
|
|
#else
|
|
*piRows = ( int ) *( ( unsigned char FAR * ) MK_FP( 0x0040, 0x0084 ) ) + 1;
|
|
*piCols = ( int ) *( ( unsigned char FAR * ) MK_FP( 0x0040, 0x004A ) );
|
|
#endif
|
|
}
|
|
|
|
#if !defined(__DJGPP__)
|
|
static char FAR * hb_gt_dos_ScreenAddress( PHB_GT pGT )
|
|
{
|
|
char FAR * ptr;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_ScreenAddress(%p)", pGT));
|
|
|
|
#if defined(__WATCOMC__) && defined(__386__)
|
|
if( HB_GTSELF_ISCOLOR( pGT ) )
|
|
ptr = ( char * ) ( 0xB800 << 4 );
|
|
else
|
|
ptr = ( char * )( 0xB000 << 4 );
|
|
#else
|
|
if( HB_GTSELF_ISCOLOR( pGT ) )
|
|
ptr = ( char FAR * ) MK_FP( 0xB800, 0x0000 );
|
|
else
|
|
ptr = ( char FAR * ) MK_FP( 0xB000, 0x0000 );
|
|
#endif
|
|
|
|
return ptr;
|
|
}
|
|
|
|
BYTE FAR * hb_gt_dos_ScreenPtr( int iRow, int iCol )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_ScreenPtr(%d, %d)", iRow, iCol));
|
|
|
|
return s_pScreenAddres + ( ( ( iRow * s_iCols ) + iCol ) << 1 );
|
|
}
|
|
#endif
|
|
|
|
static void hb_gt_dos_GetScreenContents( PHB_GT pGT )
|
|
{
|
|
int iRow, iCol;
|
|
BYTE bAttr, bChar;
|
|
#if !defined(__DJGPP__)
|
|
BYTE * pScreenPtr = s_pScreenAddres;
|
|
#endif
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetScreenContents(%p)", pGT));
|
|
|
|
for( iRow = 0; iRow < s_iRows; ++iRow )
|
|
{
|
|
for( iCol = 0; iCol < s_iCols; ++iCol )
|
|
{
|
|
#if defined(__DJGPP__TEXT)
|
|
short ch_attr;
|
|
gettext( iCol + 1, iRow + 1, iCol + 1, iRow + 1, &ch_attr );
|
|
bChar = ch_attr & 0xFF;
|
|
bAttr = ch_attr >> 8;
|
|
#elif defined(__DJGPP__)
|
|
int iChar, iAttr;
|
|
ScreenGetChar( &iChar, &iAttr, iCol, iRow );
|
|
bAttr = iAttr;
|
|
bChar = iChar;
|
|
#else
|
|
bChar = *pScreenPtr;
|
|
bAttr = *( pScreenPtr + 1 );
|
|
pScreenPtr += 2;
|
|
#endif
|
|
HB_GTSELF_PUTSCRCHAR( pGT, iRow, iCol, bAttr, 0, s_charTransRev[ bChar ] );
|
|
}
|
|
}
|
|
HB_GTSELF_COLDAREA( pGT, 0, 0, s_iRows, s_iCols );
|
|
}
|
|
|
|
static void hb_gt_dos_GetCursorPosition( int * piRow, int * piCol )
|
|
{
|
|
union REGS regs;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetCursorPosition(%p, %p)", piRow, piCol));
|
|
|
|
regs.h.ah = 0x03;
|
|
regs.h.bh = 0;
|
|
HB_DOS_INT86( 0x10, ®s, ®s );
|
|
*piRow = regs.h.dh;
|
|
*piCol = regs.h.dl;
|
|
}
|
|
|
|
static void hb_gt_dos_SetCursorPosition( int iRow, int iCol )
|
|
{
|
|
union REGS regs;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_SetCursorPosition(%d, %d)", iRow, iCol));
|
|
|
|
if( s_iCurRow != iRow || s_iCurCol != iCol )
|
|
{
|
|
regs.h.ah = 0x02;
|
|
regs.h.bh = 0;
|
|
regs.h.dh = ( BYTE ) iRow;
|
|
regs.h.dl = ( BYTE ) iCol;
|
|
HB_DOS_INT86( 0x10, ®s, ®s );
|
|
s_iCurRow = iRow;
|
|
s_iCurCol = iCol;
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_SetCursorSize( unsigned char start, unsigned char end )
|
|
{
|
|
union REGS regs;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_SetCursorSize(%d, %d)", (int) start, (int) end));
|
|
|
|
regs.h.ah = 0x01;
|
|
regs.h.ch = start;
|
|
regs.h.cl = end;
|
|
HB_DOS_INT86( 0x10, ®s, ®s );
|
|
}
|
|
|
|
static void hb_gt_dos_GetCursorSize( unsigned char * start, unsigned char *end )
|
|
{
|
|
union REGS regs;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetCursorSize(%p, %p)", start, end));
|
|
|
|
regs.h.ah = 0x03;
|
|
regs.h.bh = 0;
|
|
HB_DOS_INT86( 0x10, ®s, ®s );
|
|
*start = regs.h.ch;
|
|
*end = regs.h.cl;
|
|
}
|
|
|
|
static int hb_gt_dos_GetCursorStyle( void )
|
|
{
|
|
unsigned char start, end;
|
|
int iStyle;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetCursorStyle()"));
|
|
|
|
hb_gt_dos_GetCursorSize( &start, &end );
|
|
|
|
if( start == 32 && end == 32 )
|
|
iStyle = SC_NONE;
|
|
|
|
else if( start == 6 && end == 7 )
|
|
iStyle = SC_NORMAL;
|
|
|
|
else if( start == 4 && end == 7 )
|
|
iStyle = SC_INSERT;
|
|
|
|
else if( start == 0 && end == 7 )
|
|
iStyle = SC_SPECIAL1;
|
|
|
|
else if( start == 0 && end == 3 )
|
|
iStyle = SC_SPECIAL2;
|
|
|
|
else
|
|
iStyle = -1;
|
|
|
|
return iStyle;
|
|
}
|
|
|
|
static void hb_gt_dos_SetCursorStyle( int iStyle )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_SetCursorStyle(%d)", iStyle));
|
|
|
|
if( iStyle != s_iCursorStyle )
|
|
{
|
|
switch( iStyle )
|
|
{
|
|
case SC_NONE:
|
|
hb_gt_dos_SetCursorSize( 32, 32 );
|
|
break;
|
|
|
|
case SC_NORMAL:
|
|
hb_gt_dos_SetCursorSize( 6, 7 );
|
|
break;
|
|
|
|
case SC_INSERT:
|
|
hb_gt_dos_SetCursorSize( 4, 7 );
|
|
break;
|
|
|
|
case SC_SPECIAL1:
|
|
hb_gt_dos_SetCursorSize( 0, 7 );
|
|
break;
|
|
|
|
case SC_SPECIAL2:
|
|
hb_gt_dos_SetCursorSize( 0, 3 );
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
s_iCursorStyle = iStyle;
|
|
}
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
static BOOL s_fMousePresent = FALSE; /* Is there a mouse ? */
|
|
static BOOL s_fMouseVisible = FALSE; /* Is mouse cursor visible ? */
|
|
static int s_iMouseButtons = 0; /* Mouse buttons */
|
|
static int s_iMouseInitCol = 0; /* Init mouse pos */
|
|
static int s_iMouseInitRow = 0; /* Init mouse pos */
|
|
static BOOL s_fMouseBound;
|
|
static int s_iMouseTop;
|
|
static int s_iMouseLeft;
|
|
static int s_iMouseBottom;
|
|
static int s_iMouseRight;
|
|
|
|
#ifdef HB_MOUSE_SAVE
|
|
static int s_iMouseStorageSize = 0; /* size of mouse storage buffer */
|
|
#endif
|
|
|
|
static void hb_gt_dos_mouse_Init( PHB_GT pGT )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 0;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
s_fMousePresent = regs.HB_XREGS.ax;
|
|
if( s_fMousePresent )
|
|
{
|
|
s_iMouseButtons = regs.HB_XREGS.bx;
|
|
if( s_iMouseButtons == 0 )
|
|
s_iMouseButtons = 3;
|
|
if( s_iMouseButtons == 0xffff )
|
|
s_iMouseButtons = 2;
|
|
|
|
s_iMouseInitCol = HB_GTSELF_MOUSECOL( pGT );
|
|
s_iMouseInitRow = HB_GTSELF_MOUSEROW( pGT );
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_Exit( PHB_GT pGT )
|
|
{
|
|
if( s_fMousePresent )
|
|
{
|
|
int iHeight, iWidth;
|
|
|
|
HB_GTSELF_GETSIZE( pGT, &iHeight, &iWidth );
|
|
HB_GTSELF_MOUSESETPOS( pGT, s_iMouseInitRow, s_iMouseInitCol );
|
|
HB_GTSELF_MOUSESETBOUNDS( pGT, 0, 0, iHeight - 1, iWidth - 1 );
|
|
s_fMousePresent = FALSE;
|
|
}
|
|
}
|
|
|
|
static BOOL hb_gt_dos_mouse_IsPresent( PHB_GT pGT )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
return s_fMousePresent;
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_Show( PHB_GT pGT )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 1;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
s_fMouseVisible = TRUE;
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_Hide( PHB_GT pGT )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 2;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
s_fMouseVisible = FALSE;
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_GetPos( PHB_GT pGT, int * piRow, int * piCol )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 3;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
*piRow = regs.HB_XREGS.dx >> 3;
|
|
*piCol = regs.HB_XREGS.cx >> 3;
|
|
}
|
|
else
|
|
*piRow = *piCol = 0;
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_SetPos( PHB_GT pGT, int iRow, int iCol )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 4;
|
|
regs.HB_XREGS.dx = iRow << 3;
|
|
regs.HB_XREGS.cx = iCol << 3;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
}
|
|
}
|
|
|
|
static int hb_gt_dos_mouse_CountButton( PHB_GT pGT )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
return s_iMouseButtons;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_mouse_ButtonState( PHB_GT pGT, int iButton )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 3;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
if( regs.HB_XREGS.bx & ( 1 << iButton ) )
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_mouse_ButtonPressed( PHB_GT pGT, int iButton, int * piRow, int * piCol )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 5;
|
|
regs.HB_XREGS.bx = iButton;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
if( regs.HB_XREGS.bx )
|
|
{
|
|
*piRow = regs.HB_XREGS.dx >> 3;
|
|
*piCol = regs.HB_XREGS.cx >> 3;
|
|
return TRUE;
|
|
}
|
|
}
|
|
*piRow = *piCol = 0;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_mouse_ButtonReleased( PHB_GT pGT, int iButton, int * piRow, int * piCol )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 6;
|
|
regs.HB_XREGS.bx = iButton;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
if( regs.HB_XREGS.bx )
|
|
{
|
|
*piRow = regs.HB_XREGS.dx >> 3;
|
|
*piCol = regs.HB_XREGS.cx >> 3;
|
|
return TRUE;
|
|
}
|
|
}
|
|
*piRow = *piCol = 0;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef HB_MOUSE_SAVE
|
|
static int hb_gt_dos_mouse_StorageSize( PHB_GT pGT )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
int iSize = 0;
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 0x15;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
s_iMouseStorageSize = regs.HB_XREGS.bx;
|
|
if( s_iMouseStorageSize )
|
|
iSize = s_iMouseStorageSize + 1;
|
|
}
|
|
return iSize;
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_SaveState( PHB_GT pGT, BYTE * pBuffer )
|
|
{
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
struct SREGS sregs;
|
|
|
|
memset( &sregs, 0, sizeof( struct SREGS ) );
|
|
|
|
#if defined( __DJGPP__ )
|
|
{
|
|
_go32_dpmi_seginfo info;
|
|
|
|
info.size = ( s_iMouseStorageSize + 15 ) >> 4;
|
|
_go32_dpmi_allocate_dos_memory( &info );
|
|
|
|
regs.HB_XREGS.ax = 0x16;
|
|
regs.HB_XREGS.bx = s_iMouseStorageSize;
|
|
regs.HB_XREGS.dx = 0;
|
|
sregs.es = info.rm_segment;
|
|
|
|
HB_DOS_INT86X( 0x33, ®s, ®s, &sregs );
|
|
|
|
dosmemget( info.rm_segment << 4, s_iMouseStorageSize, pBuffer );
|
|
_go32_dpmi_free_dos_memory(&info);
|
|
}
|
|
#else
|
|
regs.HB_XREGS.ax = 0x16;
|
|
regs.HB_XREGS.bx = s_iMouseStorageSize;
|
|
regs.HB_XREGS.dx = FP_OFF( pBuffer );
|
|
sregs.es = FP_SEG( pBuffer );
|
|
HB_DOS_INT86X( 0x33, ®s, ®s, &sregs );
|
|
#endif
|
|
pBuffer[ s_iMouseStorageSize ] = HB_GTSELF_MOUSEGETCURSOR( pGT ) ? 1 : 0;
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_RestoreState( PHB_GT pGT, BYTE * pBuffer )
|
|
{
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
struct SREGS sregs;
|
|
|
|
memset( &sregs, 0, sizeof( struct SREGS ) );
|
|
|
|
/*
|
|
* Calling hb_mouse_SetCursor is necessary only for
|
|
* synchronization of internal variable s_fMouseVisible
|
|
* because the real mouse cursor state will be also recovered
|
|
* by status restoring
|
|
*/
|
|
HB_GTSELF_MOUSESETCURSOR( pGT, pBuffer[ s_iMouseStorageSize ] );
|
|
|
|
#if defined( __DJGPP__ )
|
|
{
|
|
_go32_dpmi_seginfo info;
|
|
|
|
info.size = ( s_iMouseStorageSize + 15 ) >> 4;
|
|
_go32_dpmi_allocate_dos_memory( &info );
|
|
|
|
regs.HB_XREGS.ax = 0x17;
|
|
regs.HB_XREGS.bx = s_iMouseStorageSize;
|
|
regs.HB_XREGS.dx = 0;
|
|
sregs.es = info.rm_segment;
|
|
|
|
HB_DOS_INT86X( 0x33, ®s, ®s, &sregs );
|
|
|
|
dosmemput( pBuffer, s_iMouseStorageSize, info.rm_segment << 4 );
|
|
_go32_dpmi_free_dos_memory(&info);
|
|
}
|
|
#else
|
|
regs.HB_XREGS.ax = 0x17;
|
|
regs.HB_XREGS.bx = s_iMouseStorageSize;
|
|
regs.HB_XREGS.dx = FP_OFF( pBuffer );
|
|
sregs.es = FP_SEG( pBuffer );
|
|
HB_DOS_INT86X( 0x33, ®s, ®s, &sregs );
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static void hb_gt_dos_mouse_SetBounds( PHB_GT pGT, int iTop, int iLeft, int iBottom, int iRight )
|
|
{
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( s_fMousePresent )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 7;
|
|
regs.HB_XREGS.cx = iLeft << 3;
|
|
regs.HB_XREGS.dx = iRight << 3;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
regs.HB_XREGS.ax = 8;
|
|
regs.HB_XREGS.cx = iTop << 3;
|
|
regs.HB_XREGS.dx = iBottom << 3;
|
|
HB_DOS_INT86( 0x33, ®s, ®s );
|
|
|
|
s_iMouseTop = iTop;
|
|
s_iMouseLeft = iLeft;
|
|
s_iMouseBottom = iBottom;
|
|
s_iMouseRight = iRight;
|
|
s_fMouseBound = TRUE;
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_mouse_GetBounds( PHB_GT pGT, int * piTop, int * piLeft, int * piBottom, int * piRight )
|
|
{
|
|
if( s_fMouseBound )
|
|
{
|
|
*piTop = s_iMouseTop;
|
|
*piLeft = s_iMouseLeft;
|
|
*piBottom = s_iMouseBottom;
|
|
*piRight = s_iMouseRight;
|
|
}
|
|
else
|
|
{
|
|
*piTop = *piLeft = 0;
|
|
HB_GTSELF_GETSIZE( pGT, piBottom, piRight );
|
|
--(*piBottom);
|
|
--(*piRight);
|
|
}
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
static void hb_gt_dos_Init( PHB_GT pGT, FHANDLE hFilenoStdin, FHANDLE hFilenoStdout, FHANDLE hFilenoStderr )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_Init(%p,%p,%p,%p)", pGT, hFilenoStdin, hFilenoStdout, hFilenoStderr));
|
|
|
|
s_bBreak = FALSE;
|
|
|
|
/* Set the Ctrl+Break handler [vszakats] */
|
|
|
|
#if defined(__DJGPP__)
|
|
|
|
gppconio_init();
|
|
__djgpp_hwint_flags |= 2; /* Count Ctrl+Break instead of killing program */
|
|
__djgpp_set_ctrl_c( 0 ); /* Disable Ctrl+C */
|
|
__djgpp_set_sigquit_key( 0 ); /* Disable Ctrl+\ */
|
|
|
|
#elif defined(__RSX32__)
|
|
|
|
/* TODO */
|
|
|
|
#elif defined(__WATCOMC__)
|
|
|
|
signal( SIGBREAK, hb_gt_dos_CtrlBreak_Handler );
|
|
atexit( hb_gt_dos_CtrlBrkRestore );
|
|
|
|
#elif defined(_MSC_VER)
|
|
|
|
signal( SIGINT, hb_gt_dos_CtrlBreak_Handler );
|
|
atexit( hb_gt_dos_CtrlBrkRestore );
|
|
|
|
#else
|
|
|
|
ctrlbrk( hb_gt_dos_CtrlBrkHandler );
|
|
s_iOldCtrlBreak = getcbrk();
|
|
setcbrk( 1 );
|
|
atexit( hb_gt_dos_CtrlBrkRestore );
|
|
|
|
#endif
|
|
|
|
/* initialize code page translation */
|
|
HB_GTSELF_SETDISPCP( pGT, NULL, NULL, FALSE );
|
|
HB_GTSELF_SETKEYCP( pGT, NULL, NULL );
|
|
|
|
s_iScreenMode = hb_gt_dos_GetScreenMode();
|
|
#if !defined(__DJGPP__)
|
|
s_pScreenAddres = hb_gt_dos_ScreenAddress( pGT );
|
|
#endif
|
|
hb_gt_dos_GetScreenSize( &s_iRows, &s_iCols );
|
|
hb_gt_dos_GetCursorPosition( &s_iCurRow, &s_iCurCol );
|
|
s_iCursorStyle = hb_gt_dos_GetCursorStyle();
|
|
HB_GTSUPER_INIT( pGT, hFilenoStdin, hFilenoStdout, hFilenoStderr );
|
|
HB_GTSELF_RESIZE( pGT, s_iRows, s_iCols );
|
|
hb_gt_dos_GetScreenContents( pGT );
|
|
HB_GTSELF_SETPOS( pGT, s_iCurRow, s_iCurCol );
|
|
if( s_iCursorStyle > 0 )
|
|
HB_GTSELF_SETCURSORSTYLE( pGT, s_iCursorStyle );
|
|
}
|
|
|
|
static void hb_gt_dos_Exit( PHB_GT pGT )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_Exit(%p)", pGT));
|
|
|
|
HB_GTSUPER_EXIT( pGT );
|
|
}
|
|
|
|
static int hb_gt_dos_ReadKey( PHB_GT pGT, int iEventMask )
|
|
{
|
|
int ch = 0;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_ReadKey(%p,%d)", pGT, iEventMask));
|
|
|
|
#if defined(__DJGPP__)
|
|
/* Check to see if Ctrl+Break has been detected */
|
|
if( __djgpp_cbrk_count )
|
|
{
|
|
__djgpp_cbrk_count = 0; /* Indicate that Ctrl+Break has been handled */
|
|
ch = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */
|
|
}
|
|
#else
|
|
/* First check for Ctrl+Break, which is handled by gt/gtdos.c,
|
|
with the exception of the DJGPP compiler */
|
|
if( s_bBreak )
|
|
{
|
|
s_bBreak = FALSE; /* Indicate that Ctrl+Break has been handled */
|
|
ch = HB_BREAK_FLAG; /* Note that Ctrl+Break was pressed */
|
|
}
|
|
#endif
|
|
else if( kbhit() )
|
|
{
|
|
/* A key code is available in the BIOS keyboard buffer, so read it */
|
|
#if defined(__DJGPP__)
|
|
if( iEventMask & INKEY_RAW ) ch = getxkey();
|
|
else ch = getkey();
|
|
if( ch == 256 )
|
|
/* Ignore Ctrl+Break, because it is being handled as soon as it
|
|
happens (see above) rather than waiting for it to show up in
|
|
the keyboard input queue */
|
|
ch = -1;
|
|
#else
|
|
/* A key code is available in the BIOS keyboard buffer */
|
|
ch = getch(); /* Get the key code */
|
|
if( ch == 0 && kbhit() )
|
|
{
|
|
/* It was a function key lead-in code, so read the actual
|
|
function key and then offset it by 256 */
|
|
ch = getch() + 256;
|
|
}
|
|
else if( ch == 224 && kbhit() )
|
|
{
|
|
/* It was an extended function key lead-in code, so read
|
|
the actual function key and then offset it by 256,
|
|
unless extended keyboard events are allowed, in which
|
|
case offset it by 512 */
|
|
if( iEventMask & INKEY_RAW ) ch = getch() + 512;
|
|
else ch = getch() + 256;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
ch = hb_gt_dos_keyCodeTranslate( ch );
|
|
|
|
if( ch == 0 )
|
|
ch = HB_GTSELF_MOUSEREADKEY( pGT, iEventMask );
|
|
else if( ch > 0 && ch <= 255 )
|
|
ch = s_keyTrans[ ch ];
|
|
|
|
return ch;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_IsColor( PHB_GT pGT )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_IsColor(%p)", pGT));
|
|
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
return s_iScreenMode != 7;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_GetBlink( PHB_GT pGT )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_GetBlink(%p)", pGT));
|
|
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
#if defined(__WATCOMC__) && defined(__386__)
|
|
return ( *( ( char * ) 0x0465 ) & 0x10 ) != 0;
|
|
#elif defined(__DJGPP__)
|
|
return ( _farpeekb( 0x0040, 0x0065 ) & 0x10 ) != 0;
|
|
#else
|
|
return ( *( ( char FAR * ) MK_FP( 0x0040, 0x0065 ) ) &0x10 ) != 0;
|
|
#endif
|
|
}
|
|
|
|
static void hb_gt_dos_SetBlink( PHB_GT pGT, BOOL fBlink )
|
|
{
|
|
union REGS regs;
|
|
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_SetBlink(%p,%d)", pGT, (int) fBlink));
|
|
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
regs.h.ah = 0x10;
|
|
regs.h.al = 0x03;
|
|
regs.h.bh = 0;
|
|
regs.h.bl = fBlink ? 1 : 0;
|
|
HB_DOS_INT86( 0x10, ®s, ®s );
|
|
}
|
|
|
|
static void hb_gt_dos_Tone( PHB_GT pGT, double dFrequency, double dDuration )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_Tone(%p,%lf,%lf)", pGT, dFrequency, dDuration));
|
|
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
dFrequency = HB_MIN( HB_MAX( 0.0, dFrequency ), 32767.0 );
|
|
|
|
#if defined(__BORLANDC__) || defined(__WATCOMC__)
|
|
sound( ( unsigned ) dFrequency );
|
|
#elif defined(__DJGPP__)
|
|
sound( ( int ) dFrequency );
|
|
#endif
|
|
|
|
/* convert Clipper (DOS) timer tick units to seconds ( x / 18.2 ) */
|
|
hb_idleSleep( dDuration / 18.2 );
|
|
|
|
#if defined(__BORLANDC__) || defined(__WATCOMC__)
|
|
nosound();
|
|
#elif defined(__DJGPP__)
|
|
sound( 0 );
|
|
#endif
|
|
}
|
|
|
|
static char * hb_gt_dos_Version( PHB_GT pGT, int iType )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_Version(%p,%d)", pGT, iType ) );
|
|
|
|
HB_SYMBOL_UNUSED( pGT );
|
|
|
|
if( iType == 0 )
|
|
return HB_GT_DRVNAME( HB_GT_NAME );
|
|
|
|
return "Harbour Terminal: DOS console";
|
|
}
|
|
|
|
/* some definitions */
|
|
#define INT_VIDEO 0x10
|
|
|
|
#if defined(__DJGPP__)
|
|
#define POKE_BYTE( s, o, b ) /* Do nothing */
|
|
#define outport outportw /* Use correct function name */
|
|
#elif defined(__RSX32__)
|
|
#define inportb( p ) 0 /* Return 0 */
|
|
#define outport( p, w ) /* Do nothing */
|
|
#define outportb( p, b ) /* Do nothing */
|
|
#define POKE_BYTE( s, o, b ) (*((BYTE FAR *)MK_FP((s),(o)) )=(BYTE)(b))
|
|
#elif defined(__WATCOMC__)
|
|
#define outportb outp /* Use correct function name */
|
|
#define outport outpw /* Use correct function name */
|
|
#define inport inpw /* Use correct function name */
|
|
#define inportb inp /* Use correct function name */
|
|
#define POKE_BYTE( s, o, b ) (*((BYTE FAR *)MK_FP((s),(o)) )=(BYTE)(b))
|
|
#else
|
|
#define POKE_BYTE( s, o, b ) (*((BYTE FAR *)MK_FP((s),(o)) )=(BYTE)(b))
|
|
#endif
|
|
|
|
static void vmode12x40( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x0001; /* video mode 40 cols */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
outportb( 0x03D4, 0x09 ); /* update cursor size / pointers */
|
|
regs.h.al = ( inportb( 0x03D5 ) | 0x80 );
|
|
outportb( 0x03D5, regs.h.al );
|
|
POKE_BYTE( 0x40, 0x84, 11); /* 11 rows number update */
|
|
}
|
|
|
|
static void vmode25x40( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x0001;
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
}
|
|
|
|
static void vmode28x40( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x0001; /* video mode 40 cols */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.bx = 0; /* load block 0 (BL = 0) */
|
|
regs.HB_XREGS.ax = 0x1111; /* load 8x8 monochrome char set into RAM */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
}
|
|
|
|
static void vmode50x40( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x0001;
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.bx = 0; /* load block 0 (BL = 0) */
|
|
regs.HB_XREGS.ax = 0x1112; /* load 8x8 double dot char set into RAM */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
outport( 0x03D4, 0x060A );
|
|
}
|
|
|
|
static void vmode12x80( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x0003; /* mode in AL, if bit 7 is on, No CLS */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
outportb( 0x03D4, 0x09 ); /* update cursor size / pointers */
|
|
regs.h.al = ( inportb( 0x03D5 ) | 0x80 );
|
|
outportb( 0x03D5, regs.h.al );
|
|
POKE_BYTE( 0x40, 0x84, 11); /* 11 rows number update */
|
|
}
|
|
|
|
static void vmode25x80( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x1202; /* select 350 scan line mode */
|
|
regs.h.bl = 0x30;
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.ax = 0x0083; /* mode in AL, if higher bit is on, No CLS */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.bx = 0; /* load block 0 (BL = 0) */
|
|
regs.HB_XREGS.ax = 0x1114; /* load 8x14 VGA char set into RAM */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
}
|
|
|
|
static void vmode28x80( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x0003; /* mode in AL, if higher bit is on, No CLS */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.bx = 0; /* load block 0 (BL = 0) */
|
|
regs.HB_XREGS.ax = 0x1111; /* load 8x8 monochrome char set into RAM */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
}
|
|
|
|
static void vmode43x80( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x1201; /* select 350 scan line mode */
|
|
regs.h.bl = 0x30;
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.ax = 0x0003; /* mode in AL, if higher bit is on, No CLS */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.h.bh = 0x1; /* bytes per character */
|
|
regs.h.bl = 0x0; /* load block 0 */
|
|
regs.HB_XREGS.ax = 0x1112; /* load 8x8 double dot char set into RAM */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
outport( 0x03D4, 0x060A ); /* update cursor size / pointers */
|
|
POKE_BYTE( 0x40, 0x84, 42); /* 42 rows number update */
|
|
}
|
|
|
|
static void vmode50x80( void )
|
|
{
|
|
union REGS regs;
|
|
regs.HB_XREGS.ax = 0x1202; /* select 400 scan line mode */
|
|
regs.h.bl = 0x30;
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.ax = 0x0003; /* mode in AL, if bit 7 is on, No CLS */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
regs.HB_XREGS.bx = 0; /* load block 0 (BL = 0) */
|
|
regs.HB_XREGS.ax = 0x1112; /* load 8x8 double dot char set into RAM */
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
}
|
|
|
|
/***************************************************************************
|
|
* Return the display combination: monitor + video card
|
|
*
|
|
* INT 10 - VIDEO - GET DISPLAY COMBINATION CODE (PS,VGA/MCGA)
|
|
* AX = 1A00h
|
|
* Return: AL = 1Ah if function was supported
|
|
* BL = active display code (see below)
|
|
* BH = alternate display code
|
|
*
|
|
* Values for display combination code:
|
|
* 00h no display
|
|
* 01h monochrome adapter w/ monochrome display
|
|
* 02h CGA w/ color display
|
|
* 03h reserved
|
|
* 04h EGA w/ color display
|
|
* 05h EGA w/ monochrome display
|
|
* 06h PGA w/ color display
|
|
* 07h VGA w/ monochrome analog display
|
|
* 08h VGA w/ color analog display
|
|
* 09h reserved
|
|
* 0Ah MCGA w/ digital color display
|
|
* 0Bh MCGA w/ monochrome analog display
|
|
* 0Ch MCGA w/ color analog display
|
|
* FFh unknown display type
|
|
****************************************************************************/
|
|
|
|
static USHORT hb_gt_dos_GetDisplay( void )
|
|
{
|
|
union REGS regs;
|
|
|
|
regs.HB_XREGS.ax = 0x1A00;
|
|
HB_DOS_INT86( INT_VIDEO, ®s, ®s);
|
|
|
|
return ( regs.h.al == 0x1A ) ? regs.h.bl : 0xFF;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_SetMode( PHB_GT pGT, int iRows, int iCols )
|
|
{
|
|
/* HB_GTSELF_ISCOLOR( pGT ) test for color card, we need to know if it is a VGA board...*/
|
|
BOOL bIsVGA, bIsVesa, bSuccess;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ("hb_gt_dos_SetMode(%p,%d,%d)", pGT, iRows, iCols) );
|
|
|
|
bIsVGA = ( hb_gt_dos_GetDisplay() == 8 );
|
|
bIsVesa = FALSE;
|
|
|
|
/* Available modes in B&N and color screens */
|
|
if( iCols == 40 )
|
|
{
|
|
if( iRows == 12 )
|
|
vmode12x40();
|
|
else if( iRows == 25 )
|
|
vmode25x40();
|
|
else if( iRows == 28 )
|
|
vmode28x40();
|
|
else if( iRows == 50 )
|
|
vmode50x40();
|
|
}
|
|
|
|
if( bIsVGA )
|
|
{
|
|
if( iCols == 80)
|
|
{
|
|
if( iRows == 12 )
|
|
vmode12x80();
|
|
else if( iRows == 25 )
|
|
vmode25x80();
|
|
else if( iRows == 28 )
|
|
vmode28x80();
|
|
else if( iRows == 43 )
|
|
vmode43x80();
|
|
else if( iRows == 50 )
|
|
vmode50x80();
|
|
}
|
|
|
|
if( iCols > 80 && bIsVesa )
|
|
{
|
|
/* In development process
|
|
* return( hb_gt_dos_Modevesa( nMode) );
|
|
*/
|
|
}
|
|
}
|
|
|
|
hb_gt_dos_GetScreenSize( &s_iRows, &s_iCols );
|
|
|
|
/* Check for succesful */
|
|
if( s_iRows == iRows && s_iCols == iCols )
|
|
{
|
|
bSuccess = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bSuccess = FALSE;
|
|
vmode25x80();
|
|
hb_gt_dos_GetScreenSize( &s_iRows, &s_iCols );
|
|
}
|
|
s_iScreenMode = hb_gt_dos_GetScreenMode();
|
|
#if !defined(__DJGPP__)
|
|
s_pScreenAddres = hb_gt_dos_ScreenAddress( pGT );
|
|
#endif
|
|
hb_gt_dos_GetCursorPosition( &s_iCurRow, &s_iCurCol );
|
|
s_iCursorStyle = hb_gt_dos_GetCursorStyle();
|
|
HB_GTSELF_RESIZE( pGT, s_iRows, s_iCols );
|
|
hb_gt_dos_GetScreenContents( pGT );
|
|
HB_GTSELF_SETPOS( pGT, s_iCurRow, s_iCurCol );
|
|
if( s_iCursorStyle > 0 )
|
|
HB_GTSELF_SETCURSORSTYLE( pGT, s_iCursorStyle );
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
static BOOL hb_gt_dos_PostExt( PHB_GT pGT )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_PostExt(%p)", pGT));
|
|
|
|
hb_gt_dos_GetCursorPosition( &s_iCurRow, &s_iCurCol );
|
|
hb_gt_dos_GetScreenContents( pGT );
|
|
HB_GTSELF_SETPOS( pGT, s_iCurRow, s_iCurCol );
|
|
|
|
return HB_GTSUPER_POSTEXT( pGT );
|
|
}
|
|
|
|
static BOOL hb_gt_dos_Resume( PHB_GT pGT )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_dos_Resume(%p)", pGT));
|
|
|
|
s_iScreenMode = hb_gt_dos_GetScreenMode();
|
|
#if !defined(__DJGPP__)
|
|
s_pScreenAddres = hb_gt_dos_ScreenAddress( pGT );
|
|
#endif
|
|
hb_gt_dos_GetScreenSize( &s_iRows, &s_iCols );
|
|
hb_gt_dos_GetCursorPosition( &s_iCurRow, &s_iCurCol );
|
|
s_iCursorStyle = hb_gt_dos_GetCursorStyle();
|
|
HB_GTSELF_RESIZE( pGT, s_iRows, s_iCols );
|
|
hb_gt_dos_GetScreenContents( pGT );
|
|
HB_GTSELF_SETPOS( pGT, s_iCurRow, s_iCurCol );
|
|
if( s_iCursorStyle > 0 )
|
|
HB_GTSELF_SETCURSORSTYLE( pGT, s_iCursorStyle );
|
|
|
|
return HB_GTSUPER_RESUME( pGT );
|
|
}
|
|
|
|
static BOOL hb_gt_dos_SetDispCP( PHB_GT pGT, char *pszTermCDP, char *pszHostCDP, BOOL fBox )
|
|
{
|
|
int i;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_SetDispCP(%p,%s,%s,%d)", pGT, pszTermCDP, pszHostCDP, (int) fBox ) );
|
|
|
|
HB_GTSUPER_SETDISPCP( pGT, pszTermCDP, pszHostCDP, fBox );
|
|
|
|
for( i = 0; i < 256; i++ )
|
|
s_charTrans[ i ] = ( BYTE ) i;
|
|
|
|
#ifndef HB_CDP_SUPPORT_OFF
|
|
if( !pszHostCDP )
|
|
pszHostCDP = hb_cdp_page->id;
|
|
|
|
if( pszTermCDP && pszHostCDP )
|
|
{
|
|
PHB_CODEPAGE cdpTerm = hb_cdpFind( pszTermCDP ),
|
|
cdpHost = hb_cdpFind( pszHostCDP );
|
|
if( cdpTerm && cdpHost && cdpTerm != cdpHost &&
|
|
cdpTerm->nChars && cdpTerm->nChars == cdpHost->nChars )
|
|
{
|
|
for( i = 0; i < cdpHost->nChars; ++i )
|
|
{
|
|
s_charTrans[ ( BYTE ) cdpHost->CharsUpper[ i ] ] =
|
|
( BYTE ) cdpTerm->CharsUpper[ i ];
|
|
s_charTrans[ ( BYTE ) cdpHost->CharsLower[ i ] ] =
|
|
( BYTE ) cdpTerm->CharsLower[ i ];
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for( i = 0; i < 256; i++ )
|
|
s_charTransRev[ s_charTrans[ i ] ] = ( BYTE ) i;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
static BOOL hb_gt_dos_SetKeyCP( PHB_GT pGT, char *pszTermCDP, char *pszHostCDP )
|
|
{
|
|
int i;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_SetKeyCP(%p,%s,%s)", pGT, pszTermCDP, pszHostCDP ) );
|
|
|
|
HB_GTSUPER_SETKEYCP( pGT, pszTermCDP, pszHostCDP );
|
|
|
|
for( i = 0; i < 256; i++ )
|
|
s_keyTrans[ i ] = ( BYTE ) i;
|
|
|
|
#ifndef HB_CDP_SUPPORT_OFF
|
|
if( !pszHostCDP )
|
|
{
|
|
pszHostCDP = hb_cdp_page->id;
|
|
}
|
|
|
|
if( pszTermCDP && pszHostCDP )
|
|
{
|
|
PHB_CODEPAGE cdpTerm = hb_cdpFind( pszTermCDP ),
|
|
cdpHost = hb_cdpFind( pszHostCDP );
|
|
if( cdpTerm && cdpHost && cdpTerm != cdpHost &&
|
|
cdpTerm->nChars && cdpTerm->nChars == cdpHost->nChars )
|
|
{
|
|
for( i = 0; i < cdpHost->nChars; ++i )
|
|
{
|
|
s_keyTrans[ ( BYTE ) cdpHost->CharsUpper[ i ] ] =
|
|
( BYTE ) cdpTerm->CharsUpper[ i ];
|
|
s_keyTrans[ ( BYTE ) cdpHost->CharsLower[ i ] ] =
|
|
( BYTE ) cdpTerm->CharsLower[ i ];
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
static void hb_gt_dos_Redraw( PHB_GT pGT, int iRow, int iCol, int iSize )
|
|
{
|
|
#if !defined(__DJGPP__)
|
|
USHORT FAR *pScreenPtr = (USHORT FAR *) hb_gt_dos_ScreenPtr( iRow, iCol );
|
|
#endif
|
|
BYTE bColor, bAttr;
|
|
USHORT usChar;
|
|
int iLen = 0;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_Redraw(%p,%d,%d,%d)", pGT, iRow, iCol, iSize ) );
|
|
|
|
while( iLen < iSize )
|
|
{
|
|
if( !HB_GTSELF_GETSCRCHAR( pGT, iRow, iCol + iLen, &bColor, &bAttr, &usChar ) )
|
|
break;
|
|
|
|
#if defined(__DJGPP__TEXT)
|
|
{
|
|
short ch_attr = ( ( short ) bColor << 8 ) | s_charTrans[ usChar & 0xff ];
|
|
puttext( iCol + iLen + 1, iRow + 1, iCol + iLen + 1, iRow + 1, &ch_attr );
|
|
}
|
|
#elif defined(__DJGPP__)
|
|
ScreenPutChar( s_charTrans[ usChar & 0xff ], bColor, iCol + iLen, iRow );
|
|
#else
|
|
*pScreenPtr++ = ( bColor << 8 ) + s_charTrans[ usChar & 0xff ];
|
|
#endif
|
|
iLen++;
|
|
}
|
|
}
|
|
|
|
static void hb_gt_dos_Refresh( PHB_GT pGT )
|
|
{
|
|
int iRow, iCol, iStyle;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_Refresh(%p)", pGT ) );
|
|
|
|
HB_GTSUPER_REFRESH( pGT );
|
|
|
|
HB_GTSELF_GETSCRCURSOR( pGT, &iRow, &iCol, &iStyle );
|
|
if( iStyle != SC_NONE )
|
|
{
|
|
if( iRow >= 0 && iCol >= 0 && iRow < s_iRows && iCol < s_iCols )
|
|
hb_gt_dos_SetCursorPosition( iRow, iCol );
|
|
else
|
|
iStyle = SC_NONE;
|
|
}
|
|
hb_gt_dos_SetCursorStyle( iStyle );
|
|
}
|
|
|
|
#define HB_BIOS_LSHIFT 0x01
|
|
#define HB_BIOS_RSHIFT 0x02
|
|
#define HB_BIOS_CTRL 0x04
|
|
#define HB_BIOS_ALT 0x08
|
|
#define HB_BIOS_SHIFT ( HB_BIOS_LSHIFT | HB_BIOS_RSHIFT )
|
|
#define HB_BIOS_SCROLL 0x10
|
|
#define HB_BIOS_NUMLOCK 0x20
|
|
#define HB_BIOS_CAPSLOCK 0x40
|
|
#define HB_BIOS_INSERT 0x80
|
|
|
|
// #define HB_PEEK_BYTE(s,o) ( *( ( UCHAR * ) ( ( (s) << 4 ) | (o) ) ) )
|
|
// #define HB_POKE_BYTE(s,o,b) *( ( UCHAR * ) ( ( (s) << 4 ) | (o) ) ) = (b)
|
|
|
|
static int hb_gt_dos_getKbdState( void )
|
|
{
|
|
int iKbdState = 0;
|
|
UCHAR ucStat;
|
|
|
|
ucStat = HB_PEEK_BYTE( 0x0040, 0x0017 );
|
|
|
|
if( ucStat & HB_BIOS_SHIFT ) iKbdState |= HB_GTI_KBD_SHIFT;
|
|
if( ucStat & HB_BIOS_CTRL ) iKbdState |= HB_GTI_KBD_CTRL;
|
|
if( ucStat & HB_BIOS_ALT ) iKbdState |= HB_GTI_KBD_ALT;
|
|
if( ucStat & HB_BIOS_SCROLL ) iKbdState |= HB_GTI_KBD_SCROLOCK;
|
|
if( ucStat & HB_BIOS_NUMLOCK ) iKbdState |= HB_GTI_KBD_NUMLOCK;
|
|
if( ucStat & HB_BIOS_CAPSLOCK ) iKbdState |= HB_GTI_KBD_CAPSLOCK;
|
|
if( ucStat & HB_BIOS_INSERT ) iKbdState |= HB_GTI_KBD_INSERT;
|
|
|
|
return iKbdState;
|
|
}
|
|
|
|
static void hb_gt_dos_setKbdState( int iKbdState )
|
|
{
|
|
UCHAR ucStat = 0;
|
|
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_SHIFT ) ? HB_BIOS_SHIFT : 0;
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_CTRL ) ? HB_BIOS_CTRL : 0;
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_ALT ) ? HB_BIOS_ALT : 0;
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_SCROLOCK ) ? HB_BIOS_SCROLL : 0;
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_NUMLOCK ) ? HB_BIOS_NUMLOCK : 0;
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_CAPSLOCK ) ? HB_BIOS_CAPSLOCK : 0;
|
|
ucStat |= ( iKbdState & HB_GTI_KBD_INSERT ) ? HB_BIOS_INSERT : 0;
|
|
|
|
HB_POKE_BYTE( 0x0040, 0x0017, ucStat );
|
|
}
|
|
|
|
static BOOL hb_gt_dos_Info( PHB_GT pGT, int iType, PHB_GT_INFO pInfo )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_gt_dos_Info(%p,%d,%p)", pGT, iType, pInfo ) );
|
|
|
|
switch ( iType )
|
|
{
|
|
case HB_GTI_FULLSCREEN:
|
|
case HB_GTI_KBDSUPPORT:
|
|
pInfo->pResult = hb_itemPutL( pInfo->pResult, TRUE );
|
|
break;
|
|
|
|
case HB_GTI_KBDSHIFTS:
|
|
pInfo->pResult = hb_itemPutNI( pInfo->pResult, hb_gt_dos_getKbdState() );
|
|
if( hb_itemType( pInfo->pNewVal ) & HB_IT_NUMERIC )
|
|
hb_gt_dos_setKbdState( hb_itemGetNI( pInfo->pNewVal ) );
|
|
break;
|
|
|
|
default:
|
|
return HB_GTSUPER_INFO( pGT, iType, pInfo );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* *********************************************************************** */
|
|
|
|
static BOOL hb_gt_FuncInit( PHB_GT_FUNCS pFuncTable )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_gt_FuncInit(%p)", pFuncTable));
|
|
|
|
pFuncTable->Init = hb_gt_dos_Init;
|
|
pFuncTable->Exit = hb_gt_dos_Exit;
|
|
pFuncTable->IsColor = hb_gt_dos_IsColor;
|
|
pFuncTable->SetMode = hb_gt_dos_SetMode;
|
|
pFuncTable->Redraw = hb_gt_dos_Redraw;
|
|
pFuncTable->Refresh = hb_gt_dos_Refresh;
|
|
pFuncTable->SetBlink = hb_gt_dos_SetBlink;
|
|
pFuncTable->GetBlink = hb_gt_dos_GetBlink;
|
|
pFuncTable->Version = hb_gt_dos_Version;
|
|
pFuncTable->Resume = hb_gt_dos_Resume;
|
|
pFuncTable->PostExt = hb_gt_dos_PostExt;
|
|
pFuncTable->Tone = hb_gt_dos_Tone;
|
|
pFuncTable->Info = hb_gt_dos_Info;
|
|
pFuncTable->SetDispCP = hb_gt_dos_SetDispCP;
|
|
pFuncTable->SetKeyCP = hb_gt_dos_SetKeyCP;
|
|
|
|
pFuncTable->ReadKey = hb_gt_dos_ReadKey;
|
|
|
|
pFuncTable->MouseInit = hb_gt_dos_mouse_Init;
|
|
pFuncTable->MouseExit = hb_gt_dos_mouse_Exit;
|
|
pFuncTable->MouseIsPresent = hb_gt_dos_mouse_IsPresent;
|
|
pFuncTable->MouseShow = hb_gt_dos_mouse_Show;
|
|
pFuncTable->MouseHide = hb_gt_dos_mouse_Hide;
|
|
pFuncTable->MouseGetPos = hb_gt_dos_mouse_GetPos;
|
|
pFuncTable->MouseSetPos = hb_gt_dos_mouse_SetPos;
|
|
pFuncTable->MouseSetBounds = hb_gt_dos_mouse_SetBounds;
|
|
pFuncTable->MouseGetBounds = hb_gt_dos_mouse_GetBounds;
|
|
pFuncTable->MouseCountButton = hb_gt_dos_mouse_CountButton;
|
|
pFuncTable->MouseButtonState = hb_gt_dos_mouse_ButtonState;
|
|
pFuncTable->MouseButtonPressed = hb_gt_dos_mouse_ButtonPressed;
|
|
pFuncTable->MouseButtonReleased = hb_gt_dos_mouse_ButtonReleased;
|
|
#ifdef HB_MOUSE_SAVE
|
|
pFuncTable->MouseStorageSize = hb_gt_dos_mouse_StorageSize;
|
|
pFuncTable->MouseSaveState = hb_gt_dos_mouse_SaveState;
|
|
pFuncTable->MouseRestoreState = hb_gt_dos_mouse_RestoreState;
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* ********************************************************************** */
|
|
|
|
static const HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ),
|
|
hb_gt_FuncInit,
|
|
HB_GTSUPER,
|
|
HB_GTID_PTR };
|
|
|
|
HB_GT_ANNOUNCE( HB_GT_NAME )
|
|
|
|
HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ )
|
|
hb_gtRegister( >Init );
|
|
HB_CALL_ON_STARTUP_END( _hb_startup_gt_Init_ )
|
|
|
|
#if defined( HB_PRAGMA_STARTUP )
|
|
#pragma startup _hb_startup_gt_Init_
|
|
#elif defined(HB_MSC_STARTUP)
|
|
#pragma data_seg( HB_MSC_START_SEGMENT )
|
|
static HB_$INITSYM hb_vm_auto__hb_startup_gt_Init_ = _hb_startup_gt_Init_;
|
|
#pragma data_seg()
|
|
#endif
|