454 lines
11 KiB
C
454 lines
11 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
#ifdef WINDOWS
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <io.h>
|
|
#include <extend.h>
|
|
#include <ctoharb.h>
|
|
#include <dates.h>
|
|
#include <set.h>
|
|
#if defined(__DJGPP__) || defined(__GNUC__)
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef USE_GTAPI
|
|
#include <gtapi.h>
|
|
#endif
|
|
|
|
HARBOUR HB___ACCEPT(void);
|
|
HARBOUR HB_DEVOUT( void );
|
|
HARBOUR HB_DEVPOS( void );
|
|
HARBOUR HB_EJECT( void );
|
|
HARBOUR HB_MAXCOL( void );
|
|
HARBOUR HB_MAXROW( void );
|
|
HARBOUR HB_OUTSTD( void );
|
|
HARBOUR HB_OUTERR( void );
|
|
HARBOUR HB_PCOL( void );
|
|
HARBOUR HB_PROW( void );
|
|
HARBOUR HB_SCROLL( void );
|
|
HARBOUR HB_SETPRC( void );
|
|
HARBOUR HB_QOUT( void );
|
|
HARBOUR HB_QQOUT( void );
|
|
|
|
static SYMBOL symbols[] = {
|
|
{ "__ACCEPT", FS_PUBLIC, HB___ACCEPT, 0 },
|
|
{ "DEVOUT" , FS_PUBLIC, HB_DEVOUT , 0 },
|
|
{ "DEVPOS" , FS_PUBLIC, HB_DEVPOS , 0 },
|
|
{ "EJECT" , FS_PUBLIC, HB_EJECT , 0 },
|
|
{ "MAXCOL" , FS_PUBLIC, HB_MAXCOL , 0 },
|
|
{ "MAXROW" , FS_PUBLIC, HB_MAXROW , 0 },
|
|
{ "OUTERR" , FS_PUBLIC, HB_OUTERR , 0 },
|
|
{ "OUTSTD" , FS_PUBLIC, HB_OUTSTD , 0 },
|
|
{ "PCOL" , FS_PUBLIC, HB_PCOL , 0 },
|
|
{ "PROW" , FS_PUBLIC, HB_PROW , 0 },
|
|
{ "SCROLL" , FS_PUBLIC, HB_SCROLL , 0 },
|
|
{ "SETPRC" , FS_PUBLIC, HB_SETPRC , 0 },
|
|
{ "QOUT" , FS_PUBLIC, HB_QOUT , 0 },
|
|
{ "QQOUT" , FS_PUBLIC, HB_QQOUT , 0 }
|
|
};
|
|
|
|
void Console__InitSymbols( void )
|
|
{
|
|
ProcessSymbols( symbols, sizeof(symbols)/sizeof( SYMBOL ) );
|
|
}
|
|
|
|
static unsigned short dev_row, dev_col, p_row, p_col;
|
|
static char CrLf [3];
|
|
|
|
void InitializeConsole( void )
|
|
{
|
|
CrLf [0] = 13;
|
|
CrLf [1] = 10;
|
|
CrLf [2] = 0;
|
|
#ifdef USE_GTAPI
|
|
dev_row = gtWhereY();
|
|
dev_col = gtWhereX();
|
|
_gtSetPos( dev_row, dev_col );
|
|
#else
|
|
dev_row = 0;
|
|
dev_col = 0;
|
|
#endif
|
|
p_row = p_col = 0;
|
|
}
|
|
|
|
USHORT hb_maxrow( void )
|
|
{
|
|
#ifdef USE_GTAPI
|
|
return _gtMaxRow ();
|
|
#else
|
|
return 23;
|
|
#endif
|
|
}
|
|
|
|
USHORT hb_maxcol( void )
|
|
{
|
|
#ifdef USE_GTAPI
|
|
return _gtMaxCol ();
|
|
#else
|
|
return 79;
|
|
#endif
|
|
}
|
|
|
|
HARBOUR HB___ACCEPT( void ) /* Internal Clipper function used in ACCEPT command */
|
|
/* Basically the simplest Clipper function to */
|
|
/* receive data. Parameter : cPrompt. Returns : cRet */
|
|
{
|
|
char *szResult = ( char * ) _xgrab(256); /* Return parameter. Limited to 255 chars */
|
|
char *szPrompt = _parc(1); /* Pass prompt */
|
|
long lLen = _parclen(1); /* Please change to long later on */
|
|
|
|
if( _pcount() == 1 ) /* cPrompt passed */
|
|
{
|
|
PushSymbol( GetDynSym( "QOUT" )->pSymbol ); /* push the symbol pointer to the Harbour stack */
|
|
PushNil(); /* places nil at self, as we are not sending a msg */
|
|
PushString( szPrompt, lLen ); /* places parameters on to the stack */
|
|
Do( 1 ); /* 1 parameter supplied. Invoke the virtual machine */
|
|
}
|
|
|
|
gets( szResult ); /* Read the data. Using gets() */
|
|
_retc( szResult );
|
|
_xfree( szResult );
|
|
}
|
|
|
|
typedef void void_func_int (char *, WORD);
|
|
|
|
/* Format items for output, then call specified output function */
|
|
static void hb_out( WORD wParam, void_func_int * hb_out_func )
|
|
{
|
|
char * szText;
|
|
PHB_ITEM pItem = _param( wParam, IT_ANY );
|
|
char szBuffer [11];
|
|
|
|
switch( _parinfo( wParam ) )
|
|
{
|
|
case IT_DATE:
|
|
szText = hb_dtoc( _pards( wParam ), szBuffer );
|
|
if( szText )
|
|
hb_out_func( szText, strlen( szText ) );
|
|
break;
|
|
|
|
case IT_DOUBLE:
|
|
case IT_INTEGER:
|
|
case IT_LONG:
|
|
szText = hb_str( pItem, 0, 0 ); /* Let hb_str() do the hard work */
|
|
if( szText )
|
|
{
|
|
hb_out_func( szText, strlen( szText ) );
|
|
_xfree( szText );
|
|
}
|
|
break;
|
|
|
|
case IT_NIL:
|
|
hb_out_func( "NIL", 3 );
|
|
break;
|
|
|
|
case IT_LOGICAL:
|
|
if( _parl( wParam ) )
|
|
hb_out_func( ".T.", 3 );
|
|
else
|
|
hb_out_func( ".F.", 3 );
|
|
break;
|
|
|
|
case IT_STRING:
|
|
hb_out_func( _parc( wParam ), _parclen( wParam ) );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Output an item to STDOUT */
|
|
static void hb_outstd( char * fpStr, WORD uiLen )
|
|
{
|
|
WORD uiCount = uiLen;
|
|
char * fpPtr = fpStr;
|
|
while( uiCount-- )
|
|
printf( "%c", *fpPtr++ );
|
|
fflush( stdout );
|
|
#ifdef USE_GTAPI
|
|
if( isatty( fileno( stdout ) ) )
|
|
{
|
|
dev_row = gtWhereY();
|
|
dev_col = gtWhereX();
|
|
_gtSetPos( dev_row, dev_col );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Output an item to STDERR */
|
|
static void hb_outerr( char * fpStr, WORD uiLen )
|
|
{
|
|
WORD uiCount = uiLen;
|
|
char * fpPtr = fpStr;
|
|
while( uiCount-- )
|
|
fprintf( stderr, "%c", *fpPtr++ );
|
|
fflush( stderr );
|
|
#ifdef USE_GTAPI
|
|
if( isatty( fileno( stdout ) ) )
|
|
{
|
|
dev_row = gtWhereY();
|
|
dev_col = gtWhereX();
|
|
_gtSetPos( dev_row, dev_col );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Output an item to the screen and/or printer and/or alternate */
|
|
static void hb_altout( char * fpStr, WORD uiLen )
|
|
{
|
|
if( hb_set.HB_SET_CONSOLE )
|
|
{
|
|
#ifdef USE_GTAPI
|
|
_gtWriteCon( fpStr, uiLen );
|
|
if( hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) || hb_set_printhan < 0 )
|
|
_gtGetPos( &dev_row, &dev_col );
|
|
#else
|
|
WORD uiCount;
|
|
for( uiCount = 0; uiCount < uiLen; uiCount++ )
|
|
printf( "%c", fpStr[ uiCount ] );
|
|
dev_col += uiLen;
|
|
if( dev_col > hb_maxcol() )
|
|
{
|
|
dev_row += (uiLen / (hb_maxcol() + 1));
|
|
dev_col -= (uiLen % (hb_maxcol() + 1));
|
|
}
|
|
#endif
|
|
}
|
|
if( hb_set.HB_SET_ALTERNATE && hb_set_althan >= 0 )
|
|
/* Print to alternate file if SET ALTERNATE ON and valid alternate file */
|
|
write( hb_set_althan, fpStr, uiLen );
|
|
if( hb_set.HB_SET_PRINTER && hb_set_printhan >= 0 )
|
|
/* Print to printer if SET PRINTER ON and valid printer file */
|
|
write( hb_set_printhan, fpStr, uiLen );
|
|
}
|
|
|
|
/* Output an item to the screen and/or printer */
|
|
static void hb_devout( char * fpStr, WORD uiLen )
|
|
{
|
|
if( hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 && hb_set_printhan >= 0 )
|
|
{
|
|
/* Display to printer if SET DEVICE TO PRINTER and valid printer file */
|
|
write( hb_set_printhan, fpStr, uiLen );
|
|
p_col += uiLen;
|
|
}
|
|
else
|
|
{
|
|
#ifdef USE_GTAPI
|
|
/* Otherwise, display to console */
|
|
_gtWrite( fpStr, uiLen );
|
|
_gtGetPos( &dev_row, &dev_col );
|
|
#else
|
|
WORD uiCount;
|
|
for( uiCount = 0; uiCount < uiLen; uiCount++ )
|
|
printf( "%c", fpStr[ uiCount ] );
|
|
dev_col += uiLen;
|
|
if( dev_col > hb_maxcol() )
|
|
{
|
|
dev_row += (uiLen / (hb_maxcol() + 1));
|
|
dev_col -= (uiLen % (hb_maxcol() + 1));
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void hb_devpos( USHORT row, USHORT col )
|
|
{
|
|
int count;
|
|
/* Position printer if SET DEVICE TO PRINTER and valid printer file
|
|
otherwise position console */
|
|
if( hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 && hb_set_printhan >= 0 )
|
|
{
|
|
if( row < p_row )
|
|
{
|
|
write( hb_set_printhan, "\x0C", 1 );
|
|
p_row = p_col = 0;
|
|
}
|
|
for( count = p_row; count < row; count++ ) write( hb_set_printhan, CrLf, strlen (CrLf) );
|
|
if( row > p_row ) p_col = 0;
|
|
for( count = p_col; count < col; count++ ) write( hb_set_printhan, " ", 1 );
|
|
p_row = row;
|
|
p_col = col;
|
|
}
|
|
else
|
|
{
|
|
#ifdef USE_GTAPI
|
|
_gtSetPos( row, col );
|
|
#else
|
|
for( count = dev_row; count < row; count++ ) printf("\n");
|
|
if( row > dev_row ) dev_col = 0;
|
|
for( count = dev_col; count < col; count++ ) printf(" ");
|
|
#endif
|
|
dev_row = row;
|
|
dev_col = col;
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_OUTSTD( void ) /* writes a list of values to the standard output device */
|
|
{
|
|
WORD w;
|
|
|
|
for( w = 0; w < _pcount(); w++ )
|
|
{
|
|
hb_out( w + 1, hb_outstd );
|
|
if( w < _pcount() - 1) hb_outstd( " ", 1 );
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_OUTERR( void ) /* writes a list of values to the standard error device */
|
|
{
|
|
WORD w;
|
|
|
|
for( w = 0; w < _pcount(); w++ )
|
|
{
|
|
hb_out( w + 1, hb_outerr );
|
|
if( w < _pcount() - 1) hb_outerr( " ", 1 );
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_QQOUT( void ) /* writes a list of values to the current device (screen or printer) and is affected by SET ALTERNATE */
|
|
{
|
|
WORD w;
|
|
|
|
for( w = 0; w < _pcount(); w++ )
|
|
{
|
|
hb_out( w + 1, hb_altout );
|
|
if( w < _pcount() - 1) hb_altout( " ", 1 );
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_QOUT( void )
|
|
{
|
|
#ifdef WINDOWS
|
|
MessageBox( 0, _parc( 1 ), "Harbour", 0 );
|
|
#else
|
|
hb_altout( CrLf, strlen (CrLf) );
|
|
HB_QQOUT();
|
|
#endif
|
|
}
|
|
|
|
HARBOUR HB_DEVPOS( void ) /* Sets the screen and/or printer position */
|
|
{
|
|
PHB_ITEM pRow, pCol;
|
|
if( _pcount() > 1 )
|
|
{
|
|
pRow = _param( 1, IT_NUMERIC );
|
|
pCol = _param( 2, IT_NUMERIC );
|
|
if( pRow && pCol )
|
|
hb_devpos( _parni( 1 ), _parni( 2 ) );
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_DEVOUT( void ) /* writes a single values to the current device (screen or printer), but is not affected by SET ALTERNATE */
|
|
{
|
|
if( _pcount() > 0 )
|
|
{
|
|
char fpOldColor[ 64 ];
|
|
fpOldColor[ 0 ] = 0;
|
|
if( _pcount() > 1 )
|
|
{
|
|
#ifdef USE_GTAPI
|
|
PHB_ITEM pColor = _param( 2, IT_STRING );
|
|
if( pColor )
|
|
{
|
|
_gtGetColorStr( fpOldColor );
|
|
_gtSetColorStr( pColor->value.szText );
|
|
}
|
|
#endif
|
|
}
|
|
hb_out( 1, hb_devout );
|
|
#ifdef USE_GTAPI
|
|
if( fpOldColor[ 0 ] ) _gtSetColorStr( fpOldColor );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_EJECT( void ) /* Ejects the current page from the printer */
|
|
{
|
|
if( hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 && hb_set_printhan >= 0 )
|
|
{
|
|
write( hb_set_printhan, "\x0C", 1 );
|
|
p_row = p_col = 0;
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_PROW( void ) /* Returns the current printer row position */
|
|
{
|
|
_retni( p_row );
|
|
}
|
|
|
|
HARBOUR HB_PCOL( void ) /* Returns the current printer row position */
|
|
{
|
|
_retni( p_col );
|
|
}
|
|
|
|
HARBOUR HB_SETPRC( void ) /* Sets the current printer row and column positions */
|
|
{
|
|
if( _pcount() > 1 )
|
|
{
|
|
PHB_ITEM pRow = _param( 1, IT_NUMERIC );
|
|
PHB_ITEM pCol = _param( 1, IT_NUMERIC );
|
|
if( pRow && pCol )
|
|
{
|
|
p_row = _parni( 1 );
|
|
p_col = _parni( 2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
HARBOUR HB_SCROLL( void ) /* Scrolls a screen region (requires the GT API) */
|
|
{
|
|
int top = 0, left = 0, bottom = hb_maxrow(), right = hb_maxcol(),
|
|
v_scroll = 0, h_scroll = 0;
|
|
|
|
if( _pcount() > 0 && _param( 1, IT_NUMERIC ) )
|
|
top = _parni( 1 );
|
|
if( _pcount() > 1 && _param( 2, IT_NUMERIC ) )
|
|
left = _parni( 2 );
|
|
if( _pcount() > 2 && _param( 3, IT_NUMERIC ) )
|
|
bottom = _parni( 3 );
|
|
if( _pcount() > 3 && _param( 4, IT_NUMERIC ) )
|
|
right = _parni( 4 );
|
|
if( _pcount() > 4 && _param( 5, IT_NUMERIC ) )
|
|
v_scroll = _parni( 5 );
|
|
if( _pcount() > 5 && _param( 6, IT_NUMERIC ) )
|
|
h_scroll = _parni( 6 );
|
|
|
|
#ifdef USE_GTAPI
|
|
_gtScroll( top, left, bottom, right, v_scroll, h_scroll );
|
|
#else
|
|
if( top == 0 && bottom == hb_maxrow()
|
|
&& left == 0 && right == hb_maxcol()
|
|
&& v_scroll == 0 && h_scroll == 0 )
|
|
{
|
|
int count;
|
|
dev_row = hb_maxrow();
|
|
for( count = 0; count < dev_row ; count++ ) printf( "\n" );
|
|
dev_row = dev_col = 0;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
HARBOUR HB_MAXROW( void ) /* Return the maximum screen row number (zero origin) */
|
|
{
|
|
_retni( hb_maxrow () );
|
|
}
|
|
|
|
HARBOUR HB_MAXCOL( void ) /* Return the maximum screen column number (zero origin) */
|
|
{
|
|
_retni( hb_maxcol () );
|
|
}
|
|
|
|
HARBOUR HB_ROW( void ) /* Return the current screen row position (zero origin) */
|
|
{
|
|
_retni( dev_row );
|
|
}
|
|
|
|
HARBOUR HB_COL( void ) /* Return the current screen column position (zero origin) */
|
|
{
|
|
_retni( dev_col );
|
|
}
|