/* * $Id$ */ /* Harbour Project source code Console management Copyright 1999 Antonio Linares 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/). */ /* Harbour Project source code http://www.Harbour-Project.org/ The following functions are Copyright 1999 Eddie Runia : __ACCEPT() The following functions are Copyright 1999 David G. Holm : adjust_pos(), hb_altout(), hb_devout(), HB_DEVOUT(), hb_devpos(), HB_DEVPOS(), hb_dispout(), HB___EJECT(), hb_max_col(), HB_MAXCOL(), hb_max_row(), HB_MAXROW(), hb_out(), hb_outerr(), HB_OUTERR(), hb_outstd(), HB_OUTSTD(), HB_PCOL(), HB_PROW(), hb_setpos(), HB_SETPOS(), HB_SETPRC(), HB_SCROLL(), and hb_consoleInitialize(). The following functions are Copyright 1999 Victor Szel : HB_SETPOSBS() HB_DISPBOX() GT version. HB_DISPBEGIN() HB_DISPEND() HB_DISPCOUNT() HB_ISCOLOR() HB_NOSNOW() HB___COLORINDEX(). See doc/hdr_tpl.txt, Version 1.2 or later, for licensing terms. */ #include "extend.h" #include "itemapi.h" #include "errorapi.h" #include "filesys.h" #include "dates.h" #include "set.h" #include "inkey.h" #include "gtapi.h" /* HARBOUR_USE_GTAPI is checked inside gtapi.h, so that we can always get the border styles */ #if defined(__GNUC__) && ! defined(__MINGW32__) #include #if defined(__DJGPP__) || defined(__CYGWIN__) || defined(HARBOUR_GCC_OS2) #include #endif #else #include #endif #if defined(OS_UNIX_COMPATIBLE) || defined(__CYGWIN__) #include #include #endif #define ACCEPT_BUFFER_LEN 256 /*length of input buffer for ACCEPT command */ #if defined(OS_UNIX_COMPATIBLE) #define CRLF_BUFFER_LEN 2 /*length of buffer for CR/LF characters */ #else #define CRLF_BUFFER_LEN 3 /*length of buffer for CR/LF characters */ #endif static USHORT s_uiDevRow; static USHORT s_uiDevCol; static USHORT s_uiPRow; static USHORT s_uiPCol; static char s_szCrLf[ CRLF_BUFFER_LEN ]; void hb_consoleRelease( void ) { #ifdef HARBOUR_USE_GTAPI hb_gtExit(); #endif } void hb_consoleInitialize( void ) { #if defined(OS_DOS_COMPATIBLE) s_szCrLf[ 0 ] = '\r'; s_szCrLf[ 1 ] = '\n'; s_szCrLf[ 2 ] = '\0'; #else s_szCrLf[ 0 ] = '\n'; s_szCrLf[ 1 ] = '\0'; #endif s_uiPRow = s_uiPCol = 0; /* Some compilers open stdout and stderr in text mode, but Harbour needs them to be open in binary mode. */ hb_fsSetDevMode( fileno( stdout ), FM_BINARY ); hb_fsSetDevMode( fileno( stderr ), FM_BINARY ); #ifdef HARBOUR_USE_GTAPI hb_gtInit(); hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); #else s_uiDevRow = 0; s_uiDevCol = 0; #endif } char * hb_consoleGetNewLine( void ) { return s_szCrLf; } WORD hb_max_row( void ) { #ifdef HARBOUR_USE_GTAPI return hb_gtMaxRow(); #else return 23; /* QUESTION: Shouldn't this be 24 ? info@szelvesz.hu */ #endif /* ANSWER : No. ANSI terminals commonly only have 24 lines */ } WORD hb_max_col( void ) { #ifdef HARBOUR_USE_GTAPI return hb_gtMaxCol(); #else return 79; #endif } #ifndef HARBOUR_USE_GTAPI static void adjust_pos( char * pStr, ULONG len, WORD * row, WORD * col, WORD max_row, WORD max_col ) { ULONG count; char * pPtr = pStr; for( count = 0; count < len; count++ ) { switch( *pPtr++ ) { case 7: break; case 8: if( *col ) ( *col )--; else { *col = max_col; if( *row ) ( *row )--; } break; case 10: if( *row < max_row ) ( *row )++; break; case 13: *col = 0; break; default: if( *col < max_col ) ( *col )++; else { *col = 0; if( *row < max_row ) ( *row )++; } } } } #endif typedef void hb_out_func_typedef( char *, ULONG ); /* Format items for output, then call specified output function */ static void hb_out( WORD wParam, hb_out_func_typedef * hb_out_func ) { char * szText; PHB_ITEM pItem = hb_param( wParam, IT_ANY ); switch( pItem->type ) { case IT_STRING: hb_out_func( hb_parc( wParam ), hb_parclen( wParam ) ); break; case IT_DATE: { char szBuffer[ 11 ]; szText = hb_dtoc( hb_pards( wParam ), szBuffer, hb_set.HB_SET_DATEFORMAT ); if( szText ) hb_out_func( szText, strlen( szText ) ); break; } case IT_DOUBLE: case IT_INTEGER: case IT_LONG: szText = hb_itemStr( pItem, NULL, NULL ); /* Let hb_itemStr() do the hard work */ if( szText ) { hb_out_func( szText, strlen( szText ) ); hb_xfree( szText ); } break; case IT_NIL: hb_out_func( "NIL", 3 ); break; case IT_LOGICAL: if( hb_parl( wParam ) ) hb_out_func( ".T.", 3 ); else hb_out_func( ".F.", 3 ); break; default: break; } } /* Output an item to STDOUT */ static void hb_outstd( char * pStr, ULONG len ) { ULONG count = len; char * pPtr = pStr; #ifdef HARBOUR_USE_GTAPI hb_gtPreExt(); #endif if( strlen( pStr ) != count ) while( count-- ) printf( "%c", *pPtr++ ); else printf( "%s", pStr ); fflush( stdout ); #ifdef HARBOUR_USE_GTAPI #ifndef __CYGWIN__ if( isatty( fileno( stdout ) ) ) #endif { s_uiDevRow = hb_gt_Row(); s_uiDevCol = hb_gt_Col(); hb_gtSetPos( s_uiDevRow, s_uiDevCol ); } hb_gtPostExt(); #else adjust_pos( pStr, len, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); #endif } /* Output an item to STDERR */ static void hb_outerr( char * pStr, ULONG len ) { ULONG count = len; char * pPtr = pStr; #ifdef HARBOUR_USE_GTAPI hb_gtPreExt(); #endif if( strlen( pStr ) != count ) while( count-- ) fprintf( stderr, "%c", *pPtr++ ); else fprintf( stderr, "%s", pStr ); fflush( stderr ); #ifdef HARBOUR_USE_GTAPI #ifndef __CYGWIN__ if( isatty( fileno( stderr ) ) ) #endif { s_uiDevRow = hb_gt_Row(); s_uiDevCol = hb_gt_Col(); hb_gtSetPos( s_uiDevRow, s_uiDevCol ); } hb_gtPostExt(); #else adjust_pos( pStr, len, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); #endif } /* Output an item to the screen and/or printer and/or alternate */ static void hb_altout( char * pStr, ULONG len ) { char *pPtr = pStr; if( hb_set.HB_SET_CONSOLE ) { #ifdef HARBOUR_USE_GTAPI hb_gtWriteCon( pStr, len ); hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); #else ULONG count = len; if( strlen( pStr ) != count ) while( count-- ) printf( "%c", *pPtr++ ); else printf( "%s", pStr ); adjust_pos( pStr, len, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); #endif } if( hb_set.HB_SET_ALTERNATE && hb_set_althan >= 0 ) { /* Print to alternate file if SET ALTERNATE ON and valid alternate file */ int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; pPtr = pStr; while( count ) { if( count > UINT_MAX ) { write_len = UINT_MAX; count -= UINT_MAX; } else { write_len = count; count = 0; } hb_fsWrite( hb_set_althan, ( BYTE * ) pPtr, write_len ); pPtr += write_len; } hb_fsSetError( user_ferror ); /* Restore last user file error code */ } if( hb_set_extrahan >= 0 ) { /* Print to extra file if valid alternate file */ int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; pPtr = pStr; while( count ) { if( count > UINT_MAX ) { write_len = UINT_MAX; count -= UINT_MAX; } else { write_len = count; count = 0; } hb_fsWrite( hb_set_extrahan, ( BYTE * ) pPtr, write_len ); pPtr += write_len; } hb_fsSetError( user_ferror ); /* Restore last user file error code */ } if( hb_set.HB_SET_PRINTER && hb_set_printhan >= 0 ) { /* Print to printer if SET PRINTER ON and valid printer file */ int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; pPtr = pStr; while( count ) { if( count > UINT_MAX ) { write_len = UINT_MAX; count -= UINT_MAX; } else { write_len = count; count = 0; } hb_fsWrite( hb_set_printhan, ( BYTE * ) pPtr, write_len ); pPtr += write_len; } if( len + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; else s_uiPCol += len; hb_fsSetError( user_ferror ); /* Restore last user file error code */ } } /* Output an item to the screen and/or printer */ static void hb_devout( char * pStr, ULONG len ) { if( hb_set_printhan >= 0 && hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 ) { /* Display to printer if SET DEVICE TO PRINTER and valid printer file */ int user_ferror = hb_fsError(); /* Save current user file error code */ unsigned write_len; ULONG count = len; char * pPtr = pStr; while( count ) { if( count > UINT_MAX ) { write_len = UINT_MAX; count -= UINT_MAX; } else { write_len = count; count = 0; } hb_fsWrite( hb_set_printhan, ( BYTE * ) pPtr, write_len ); pPtr += write_len; } if( len + s_uiPCol > USHRT_MAX ) s_uiPCol = USHRT_MAX; else s_uiPCol += len; hb_fsSetError( user_ferror ); /* Restore last user file error code */ } else { #ifdef HARBOUR_USE_GTAPI /* Otherwise, display to console */ hb_gtWrite( pStr, len ); hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); #else ULONG count = len; char * pPtr = pStr; if( strlen( pStr ) != count ) while( count-- ) printf( "%c", *pPtr++ ); else printf( "%s", pStr ); adjust_pos( pStr, len, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); #endif } } /* Output an item to the screen */ static void hb_dispout( char * pStr, ULONG len ) { #ifdef HARBOUR_USE_GTAPI /* Display to console */ hb_gtWrite( pStr, len ); hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); #else ULONG count = len; char * pPtr = pStr; if( strlen( pStr ) != count ) while( count-- ) printf( "%c", *pPtr++ ); else printf( "%s", pStr ); adjust_pos( pStr, len, &s_uiDevRow, &s_uiDevCol, hb_max_row(), hb_max_col() ); #endif } void hb_setpos( WORD row, WORD col ) { #ifdef HARBOUR_USE_GTAPI hb_gtSetPos( row, col ); #else WORD count; if( row < s_uiDevRow || col < s_uiDevCol ) { printf( s_szCrLf ); s_uiDevCol = 0; s_uiDevRow++; } else if( row > s_uiDevRow ) s_uiDevCol = 0; for( count = s_uiDevRow; count < row; count++ ) printf( s_szCrLf ); for( count = s_uiDevCol; count < col; count++ ) printf( " " ); #endif s_uiDevRow = row; s_uiDevCol = col; } void hb_devpos( WORD row, WORD col ) { WORD count; /* Position printer if SET DEVICE TO PRINTER and valid printer file otherwise position console */ if( hb_set_printhan >= 0 && hb_stricmp( hb_set.HB_SET_DEVICE, "PRINTER" ) == 0 ) { int user_ferror = hb_fsError(); /* Save current user file error code */ if( row < s_uiPRow ) { hb_fsWrite( hb_set_printhan, ( BYTE * ) "\x0C", 1 ); s_uiPRow = s_uiPCol = 0; } for( count = s_uiPRow; count < row; count++ ) hb_fsWrite( hb_set_printhan, ( BYTE * ) s_szCrLf, CRLF_BUFFER_LEN-1 ); if( row > s_uiPRow ) s_uiPCol = 0; col += hb_set.HB_SET_MARGIN; for( count = s_uiPCol; count < col; count++ ) hb_fsWrite( hb_set_printhan, ( BYTE * ) " ", 1 ); s_uiPRow = row; s_uiPCol = col; hb_fsSetError( user_ferror ); /* Restore last user file error code */ } else { hb_setpos( row, col ); } } HARBOUR HB_OUTSTD( void ) /* writes a list of values to the standard output device */ { WORD w, pcount = hb_pcount(); for( w = 1; w <= pcount; w++ ) { hb_out( w, hb_outstd ); if( w < pcount ) hb_outstd( " ", 1 ); } } HARBOUR HB_OUTERR( void ) /* writes a list of values to the standard error device */ { WORD w, pcount = hb_pcount(); for( w = 1; w <= pcount; w++ ) { hb_out( w, hb_outerr ); if( w < pcount ) 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, pcount = hb_pcount(); for( w = 1; w <= pcount; w++ ) { hb_out( w, hb_altout ); if( w < pcount ) hb_altout( " ", 1 ); } } HARBOUR HB_QOUT( void ) { WORD count; hb_altout( s_szCrLf, CRLF_BUFFER_LEN - 1 ); if( hb_set.HB_SET_PRINTER && hb_set_printhan >= 0 ) { int user_ferror = hb_fsError(); /* Save current user file error code */ s_uiPRow++; s_uiPCol = hb_set.HB_SET_MARGIN; count = s_uiPCol; while( count-- > 0 ) hb_fsWrite( hb_set_printhan, ( BYTE * ) " ", 1 ); hb_fsSetError( user_ferror ); /* Restore last user file error code */ } HB_QQOUT(); } HARBOUR HB_SETPOS( void ) /* Sets the screen position */ { if( hb_pcount() == 2 ) { if( ISNUM( 1 ) && ISNUM( 2 ) ) { int i_row = hb_parni( 1 ); int i_col = hb_parni( 2 ); WORD row, col; /* Limit the new position to the range (0,0) to (MAXROW(),MAXCOL()) */ if( i_row < 0 ) row = 0; else if( i_row > hb_max_row() ) row = hb_max_row(); else row = i_row; if( i_col < 0 ) col = 0; else if( i_col > hb_max_col() ) col = hb_max_col(); else col = i_col; /* Set the new screen position */ hb_setpos( row, col ); } } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "SETPOS" ); /* NOTE: Clipper catches this at compile time! */ } /* Move the screen position to the right by one column */ HARBOUR HB_SETPOSBS( void ) { if( hb_pcount() == 0 ) { USHORT uiRow; USHORT uiCol; /* NOTE: Clipper does no checks about reaching the border or anything */ #ifdef HARBOUR_USE_GTAPI hb_gtGetPos( &uiRow, &uiCol ); hb_gtSetPos( uiRow, uiCol + 1 ); #endif } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "SETPOSBS" ); /* NOTE: Clipper catches this at compile time! */ } HARBOUR HB_DEVPOS( void ) /* Sets the screen and/or printer position */ { if( hb_pcount() == 2 ) { if( ISNUM( 1 ) && ISNUM( 2 ) ) { long l_row = hb_parnl( 1 ); long l_col = hb_parnl( 2 ); WORD row, col; /* Limit the new position to the range (0,0) to (65535,65535) */ if( l_row < 0 ) row = 0; else if( l_row > USHRT_MAX ) row = USHRT_MAX; else row = l_row; if( l_col < 0 ) col = 0; else if( l_col > USHRT_MAX ) col = USHRT_MAX; else col = l_col; /* Set the new screen position */ hb_devpos( row, col ); } } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "DEVPOS" ); /* NOTE: Clipper catches this at compile time! */ } HARBOUR HB_DEVOUT( void ) /* writes a single value to the current device (screen or printer), but is not affected by SET ALTERNATE */ { if( hb_pcount() > 0 ) { #ifdef HARBOUR_USE_GTAPI char pOldColor[ CLR_STRLEN ]; if( ISCHAR( 2 ) ) { hb_gtGetColorStr( pOldColor ); hb_gtSetColorStr( hb_parc( 2 ) ); } #endif hb_out( 1, hb_devout ); #ifdef HARBOUR_USE_GTAPI if( ISCHAR( 2 ) ) hb_gtSetColorStr( pOldColor ); #endif } } HARBOUR HB_DISPOUT( void ) /* writes a single value to the current device (screen or printer), but is not affected by SET ALTERNATE */ { if( hb_pcount() > 0 ) { #ifdef HARBOUR_USE_GTAPI char pOldColor[ CLR_STRLEN ]; if( ISCHAR( 2 ) ) { hb_gtGetColorStr( pOldColor ); hb_gtSetColorStr( hb_parc( 2 ) ); } #endif hb_out( 1, hb_dispout ); #ifdef HARBOUR_USE_GTAPI if( ISCHAR( 2 ) ) hb_gtSetColorStr( pOldColor ); #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 ) { int user_ferror = hb_fsError(); /* Save current user file error code */ hb_fsWrite( hb_set_printhan, ( BYTE * ) "\x0C\x0D", 2 ); s_uiPRow = s_uiPCol = 0; hb_fsSetError( user_ferror ); /* Restore last user file error code */ } } HARBOUR HB_PROW( void ) /* Returns the current printer row position */ { if( hb_pcount() == 0 ) hb_retni( s_uiPRow ); else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "PROW" ); /* NOTE: Clipper catches this at compile time! */ } HARBOUR HB_PCOL( void ) /* Returns the current printer row position */ { if( hb_pcount() == 0 ) hb_retni( s_uiPCol ); else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "PCOL" ); /* NOTE: Clipper catches this at compile time! */ } HARBOUR HB_SETPRC( void ) /* Sets the current printer row and column positions */ { if( ISNUM( 1 ) && ISNUM( 2 ) ) { long l_row = hb_parnl( 1 ); long l_col = hb_parnl( 2 ); /* Limit the new position to the range (0,0) to (65535,65535) */ if( l_row < 0 ) s_uiPRow = 0; else if( l_row > USHRT_MAX ) s_uiPRow = USHRT_MAX; else s_uiPRow = l_row; if( l_col < 0 ) s_uiPCol = 0; else if( l_col > USHRT_MAX ) s_uiPCol = USHRT_MAX; else s_uiPCol = l_col; } } HARBOUR HB_SCROLL( void ) /* Scrolls a screen region (requires the GT API) */ { WORD top, left, bottom, right; int iMR = hb_max_row(); int iMC = hb_max_col(); int i_top = ISNUM( 1 ) ? hb_parni( 1 ) : 0; int i_left = ISNUM( 2 ) ? hb_parni( 2 ) : 0; int i_bottom = ISNUM( 3 ) ? hb_parni( 3 ) : iMR; int i_right = ISNUM( 4 ) ? hb_parni( 4 ) : iMC; int v_scroll = ISNUM( 5 ) ? hb_parni( 5 ) : 0; int h_scroll = ISNUM( 6 ) ? hb_parni( 6 ) : 0; /* Enforce limits of (0,0) to (MAXROW(),MAXCOL()) */ if( i_top < 0 ) top = 0; else if( i_top > iMR ) top = iMR; else top = i_top; if( i_left < 0 ) left = 0; else if( i_left > iMC ) left = iMC; else left = i_left; if( i_bottom < 0 ) bottom = 0; else if( i_bottom > iMR ) bottom = iMR; else bottom = i_bottom; if( i_right < 0 ) right = 0; else if( i_right > iMC ) right = iMC; else right = i_right; #ifdef HARBOUR_USE_GTAPI hb_gtScroll( top, left, bottom, right, v_scroll, h_scroll ); #else if( top == 0 && bottom == iMR && left == 0 && right == iMC && v_scroll == 0 && h_scroll == 0 ) { WORD count; s_uiDevRow = iMR; for( count = 0; count < s_uiDevRow ; count++ ) printf( s_szCrLf ); s_uiDevRow = s_uiDevCol = 0; } #endif } HARBOUR HB_MAXROW( void ) /* Return the maximum screen row number (zero origin) */ { hb_retni( hb_max_row() ); } HARBOUR HB_MAXCOL( void ) /* Return the maximum screen column number (zero origin) */ { hb_retni( hb_max_col() ); } HARBOUR HB_ROW( void ) /* Return the current screen row position (zero origin) */ { if( hb_pcount() == 0 ) { #ifdef HARBOUR_USE_GTAPI hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); #endif hb_retni( s_uiDevRow ); } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "ROW" ); /* NOTE: Clipper catches this at compile time! */ } HARBOUR HB_COL( void ) /* Return the current screen column position (zero origin) */ { if( hb_pcount() == 0 ) { #ifdef HARBOUR_USE_GTAPI hb_gtGetPos( &s_uiDevRow, &s_uiDevCol ); #endif hb_retni( s_uiDevCol ); } else hb_errRT_BASE( EG_ARGCOUNT, 3000, NULL, "COL" ); /* NOTE: Clipper catches this at compile time! */ } HARBOUR HB_DISPBOX( void ) { #ifdef HARBOUR_USE_GTAPI if( ISNUM( 1 ) && ISNUM( 2 ) && ISNUM( 3 ) && ISNUM( 4 ) ) { char szOldColor[ CLR_STRLEN ]; if( ISCHAR( 6 ) ) { hb_gtGetColorStr( szOldColor ); hb_gtSetColorStr( hb_parc( 6 ) ); } if( ISCHAR( 5 ) ) hb_gtBox( hb_parni( 1 ), hb_parni( 2 ), hb_parni( 3 ), hb_parni( 4 ), hb_parc( 5 )); else if( ISNUM( 5 ) && hb_parni( 5 ) == 2 ) hb_gtBoxD( hb_parni( 1 ), hb_parni( 2 ), hb_parni( 3 ), hb_parni( 4 ) ); else hb_gtBoxS( hb_parni( 1 ), hb_parni( 2 ), hb_parni( 3 ), hb_parni( 4 ) ); if( ISCHAR( 6 ) ) hb_gtSetColorStr( szOldColor ); } #else if( ISNUM( 1 ) && ISNUM( 2 ) && ISNUM( 3 ) && ISNUM( 4 ) ) { char * szBorderStyle = B_SINGLE; int i_top = hb_parni( 1 ), i_left = hb_parni( 2 ); int i_bottom = hb_parni( 3 ), i_right = hb_parni( 4 ); WORD top, left, bottom, right, size = strlen( B_SINGLE ); WORD row, col, width, height; char Borders[ 9 ]; /* Set limits on the box coordinates to (0,0) and (max_row(),max_col()) */ if( i_top < 0 ) top = 0; else top = ( WORD ) i_top; if( i_left < 0 ) left = 0; else left = ( WORD ) i_left; if( i_bottom < 0 ) bottom = 0; else bottom = ( WORD ) i_bottom; if( i_right < 0 ) right = 0; else right = ( WORD ) i_right; if( top > hb_max_row() ) top = hb_max_row(); if( left > hb_max_col() ) left = hb_max_col(); if( bottom > hb_max_row() ) bottom = hb_max_row(); if( right > hb_max_col() ) right = hb_max_col(); /* Force the box to be drawn from top left to bottom right */ if( top > bottom ) { int temp; temp = top; top = bottom; bottom = temp; } if( left > right ) { int temp; temp = right; right = left; left = temp; } width = right - left + 1; height = bottom - top + 1; /* Determine the box style */ if( ISCHAR( 5 ) ) { szBorderStyle = hb_parc( 5 ); size = hb_parclen( 5 ); } else if( ISNUM( 5 ) ) { switch( hb_parni( 5 ) ) { case 2: szBorderStyle = B_DOUBLE; break; case 3: szBorderStyle = B_SINGLE_DOUBLE; break; case 4: szBorderStyle = B_DOUBLE_SINGLE; break; default: szBorderStyle = B_SINGLE; } size = strlen( szBorderStyle ); } /* We only need 9 characters from the source string */ if( size > 9 ) size = 9; /* If we have at least one character... */ if( size ) /* ...copy the source string */ memcpy( Borders, szBorderStyle, size ); else /* If not, set the first character to a space */ Borders[ size++ ] = ' '; /* If there were less than 8 characters in the source... */ for( ; size < 8; size++ ) { /* ...copy the last character into the remaining 8 border positions */ Borders[ size ] = Borders[ size - 1 ]; } /* If there were less than 9 characters in the source... */ if( size < 9 ) /* ...set the fill character to space */ Borders[ 8 ] = ' '; /* Draw the box */ hb_setpos( top, left ); if( height > 1 && width > 1 ) printf( "%c", Borders[ 0 ] ); /* Upper left corner */ for( col = ( height > 1 ? left + 1 : left ); col < ( height > 1 ? right : right + 1 ); col++ ) printf( "%c", Borders[ 1 ] ); /* Top line */ if( height > 1 && width > 1 ) printf( "%c", Borders[ 2 ] ); /* Upper right corner */ for( row = ( height > 1 ? top + 1 : top ); row < ( width > 1 ? bottom : bottom + 1 ); row++ ) { hb_setpos( row, left ); if( height > 1 ) printf( "%c", Borders[ 3 ] ); /* Left side */ if( height > 1 && width > 1 ) for( col = left + 1; col < right; col++ ) printf( "%c", Borders[ 8 ] ); /* Fill */ if( height > 1 && width > 1 ) printf( "%c", Borders[ 7 ] ); /* Right side */ } if( height > 1 && width > 1 ) { hb_setpos( bottom, left ); col = left; printf( "%c", Borders[ 6 ] ); /* Bottom left corner */ for( col = left + 1; col < right; col++ ) printf( "%c", Borders[ 5 ] ); /* Bottom line */ printf( "%c", Borders[ 4 ] ); /* Bottom right corner */ } hb_setpos( bottom + 1, right + 1 ); } #endif } HARBOUR HB_DISPBEGIN( void ) { #ifdef HARBOUR_USE_GTAPI hb_gtDispBegin(); #endif } HARBOUR HB_DISPEND( void ) { #ifdef HARBOUR_USE_GTAPI hb_gtDispEnd(); #endif } HARBOUR HB_DISPCOUNT( void ) { #ifdef HARBOUR_USE_GTAPI hb_retni( hb_gtDispCount() ); #else hb_retni( 0 ); #endif } HARBOUR HB_ISCOLOR( void ) { #ifdef HARBOUR_USE_GTAPI hb_retl( hb_gtIsColor() ); #else hb_retl( FALSE ); #endif } HARBOUR HB_NOSNOW( void ) { #ifdef HARBOUR_USE_GTAPI if( ISLOG( 1 ) ) hb_gtSetSnowFlag( hb_parl( 1 ) ); #endif } HARBOUR HB___SHADOW( void ) { #ifdef HARBOUR_USE_GTAPI USHORT uiAttr; if( hb_pcount() == 4 ) uiAttr = 7; else if( hb_pcount() == 5 ) uiAttr = hb_parni( 5 ); if( hb_pcount() > 3 ) hb_gt_DrawShadow( hb_parni( 1 ) + 1, hb_parni( 2 ) + 1, hb_parni( 3 ) + 1, hb_parni( 4 ) + 1, uiAttr ); #endif } HARBOUR HB_DBGSHADOW( void ) { HB___SHADOW(); } HARBOUR HB_SAVESCREEN( void ) { #ifdef HARBOUR_USE_GTAPI USHORT uiX; USHORT uiCoords[ 4 ]; char * pBuffer; uiCoords[ 0 ] = 0; uiCoords[ 1 ] = 0; uiCoords[ 2 ] = hb_gtMaxRow(); uiCoords[ 3 ] = hb_gtMaxCol(); for( uiX = 1; uiX <= 4; uiX++ ) if( ISNUM( uiX ) ) uiCoords[ uiX - 1 ] = hb_parni( uiX ); hb_gtRectSize( uiCoords[ 0 ], uiCoords[ 1 ], uiCoords[ 2 ], uiCoords[ 3 ], &uiX ); pBuffer = ( char * ) hb_xgrab( uiX ); hb_gtSave( uiCoords[ 0 ], uiCoords[ 1 ], uiCoords[ 2 ], uiCoords[ 3 ], pBuffer ); hb_retclen( pBuffer, uiX ); hb_xfree( ( void * ) pBuffer ); #else hb_retc( "" ); #endif } HARBOUR HB_RESTSCREEN( void ) { #ifdef HARBOUR_USE_GTAPI if( hb_pcount() == 5 ) { USHORT uiX; USHORT uiCoords[ 4 ]; uiCoords[ 0 ] = 0; uiCoords[ 1 ] = 0; uiCoords[ 2 ] = hb_gtMaxRow(); uiCoords[ 3 ] = hb_gtMaxCol(); for( uiX = 1; uiX < 5; uiX++ ) if( ISNUM( uiX ) ) uiCoords[ uiX - 1 ] = hb_parni( uiX ); hb_gtRest( uiCoords[ 0 ], uiCoords[ 1 ], uiCoords[ 2 ], uiCoords[ 3 ], hb_parc( 5 ) ); } #endif } HARBOUR HB_SETCURSOR( void ) { #ifdef HARBOUR_USE_GTAPI USHORT usPreviousCursor; hb_gtGetCursor( &usPreviousCursor ); if( hb_pcount() == 1 ) hb_gtSetCursor( hb_parni( 1 ) ); hb_retni( usPreviousCursor ); #else hb_retni( SC_NORMAL ); #endif } HARBOUR HB_SETBLINK( void ) { #ifdef HARBOUR_USE_GTAPI BOOL bPreviousBlink; hb_gtGetBlink( &bPreviousBlink ); if( ISLOG( 1 ) ) hb_gtSetBlink( hb_parl( 1 ) ); hb_retl( bPreviousBlink ); #else hb_retl( FALSE ); #endif } HARBOUR HB_SETMODE( void ) { #ifdef HARBOUR_USE_GTAPI if( ISNUM( 1 ) && ISNUM( 2 ) ) hb_gtSetMode( hb_parni( 1 ), hb_parni( 2 ) ); #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 * ) hb_xgrab( ACCEPT_BUFFER_LEN ); /* Return parameter. */ char * szPrompt = hb_parc( 1 ); /* Pass prompt */ ULONG len = hb_parclen( 1 ); int input; if( hb_pcount() == 1 ) /* cPrompt passed */ { hb_altout( s_szCrLf, CRLF_BUFFER_LEN - 1 ); hb_altout( szPrompt, len ); } #if defined (OS_UNIX_COMPATIBLE) || defined(__CYGWIN__) /* Read the data using fgets(), because hb_inkeyPoll() doesn't support Unix compatible operating systems yet. */ { /* Set up for echoed canonical input */ struct termios ta; tcgetattr( STDIN_FILENO, &ta ); ta.c_lflag |= ( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSAFLUSH, &ta ); /* Avoid an undefined variable warning */ input = 0; /* Get a line of user input */ szResult[ 0 ] = '\0'; /* start with something defined */ if( fgets( szResult, ACCEPT_BUFFER_LEN, stdin ) ) strtok( szResult, "\n" ); /* strip off the trailing newline if it exists */ /* Restore unechoed non-canonical input */ ta.c_lflag &= ~( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSAFLUSH, &ta ); } #else len = 0; input = 0; while( input != 13 ) { /* Wait forever, for keyboard events only */ input = hb_inkey ( 0.0, INKEY_KEYBOARD, 1, 1 ); switch( input ) { case 8: /* Backspace */ case 19: /* Left arrow */ if( len > 0 ) { len--; /* Adjust input count to get rid of last character, then erase it from the screen. */ #ifdef HARBOUR_USE_GTAPI hb_gtWriteCon( "\x8 \x8", 3L ); #else printf( "\x8 \x8" ); #endif } break; case 13: /* Nothing to do. While loop will now exit. */ break; default: if( len < 255 && input >= 32 && input <= 127 ) { szResult[ len ] = input; /* Accept the input */ hb_dispout( &szResult[ len ], 1 ); /* Then display it */ len++; /* Then adjust the input count */ } } } #endif hb_retclen( szResult, len ); hb_xfree( szResult ); } /* ------------------------------------------------- */ /* Copyright (C) 1999 Victor Szel */ /* ------------------------------------------------- */ /* $DOC$ * $FUNCNAME$ * __ColorIndex * $CATEGORY$ * GT * $ONELINER$ * Extract one color from a full Clipper colorspec string. * $SYNTAX$ * __ColorIndex( , ) * $ARGUMENTS$ * is a Clipper color list * is the position of the color item to be extracted, the first * position is the zero. * $RETURNS$ * The selected color string, or if anything goes wrong, and empty * string * $DESCRIPTION$ * Clipper has color spec string, which have more than one single * colors in it, separated with commas. This function is able to extract * a given item from this list. You may use the manifest constants * defined in color.ch to extract common Clipper colors. * $EXAMPLES$ * ? __ColorIndex( "W/N, N/W", CLR_ENHANCED ) // "N/W" * $TESTS$ * see in rtl_test.prg for a comprehensive regression test suit. * $STATUS$ * R * $COMPLIANCE$ * Was not part of CA-Clipper. * $SEEALSO$ * ColorSelect() * $END$ */ HARBOUR HB___COLORINDEX( void ) { if( ISCHAR( 1 ) && ISNUM( 2 ) ) { char * szColor = hb_parc( 1 ); ULONG ulColorPos; ULONG ulColorLen; USHORT uiColorIndex = ( USHORT ) hb_parni( 2 ); /* Skip the given number of commas */ for( ulColorPos = 0 ; szColor[ ulColorPos ] != '\0' && uiColorIndex > 0 ; ulColorPos++ ) { if( szColor[ ulColorPos ] == ',' ) uiColorIndex--; } /* if found, continue */ if( uiColorIndex == 0 ) { /* Skip the spaces after the comma */ while( szColor[ ulColorPos ] == ' ' ) ulColorPos++; /* Search for next comma or end of string */ ulColorLen = 0; while( szColor[ ulColorPos + ulColorLen ] != '\0' && szColor[ ulColorPos + ulColorLen ] != ',' ) ulColorLen++; /* Skip the trailing spaces */ while( ulColorLen > 0 && szColor[ ulColorPos + ulColorLen - 1 ] == ' ' ) ulColorLen--; /* Return the string */ hb_retclen( szColor + ulColorPos, ulColorLen ); } else hb_retc( "" ); } else hb_retc( "" ); }