* tests/testsha1.prg
* tests/longdev.prg
* tests/clsccast.prg
* tests/cmphello.prg
* tests/clsicast.prg
* tests/testop.prg
* tests/clsscast.prg
* tests/objarr.prg
* tests/rddtest/rddmktst.prg
* tests/rddtest/adscl52.prg
* tests/rddtest/adscl53.prg
* tests/rddtest/ntxcl52.prg
* tests/rddtest/ntxcl53.prg
* tests/rddtest/cdxcl52.prg
* tests/rddtest/rddtst.prg
* tests/rddtest/cdxcl53.prg
* tests/transtst.prg
* tests/output.prg
* tests/ac_test2.prg
* tests/clsscope.prg
* tests/dosshell.prg
* tests/sbartest.prg
* tests/speedold.prg
* tests/sdf_test.prg
* tests/wcecon.prg
* tests/debugtst.prg
* tests/testdyn.c
* tests/multiarg.prg
* tests/fornext.prg
* tests/hbinline.prg
* tests/foreach2.prg
* tests/objasign.prg
* tests/scroll.prg
* tests/inherit.prg
* tests/rto_get.prg
* tests/boxtst2.prg
* tests/inkeytst.prg
* tests/overload.prg
* tests/cpinfo.prg
* tests/gtwin.prg
* tests/mt/mttest08.prg
* tests/mt/mttest09.prg
* tests/mt/mttest01.prg
* tests/mt/mttest10.prg
* tests/mt/mttest02.prg
* tests/mt/mttest11.prg
* tests/mt/mttest03.prg
* tests/mt/mttest12.prg
* tests/mt/mttest04.prg
* tests/mt/mttest05.prg
* tests/mt/mttest06.prg
* tests/mt/mttest07.prg
* tests/speedtst.prg
* tests/testsha2.prg
* tests/hsxtest.prg
* tests/arrayidx.prg
* tests/clsnv.prg
* tests/rto_tb.prg
* tests/gtchars.prg
* tests/disptest.prg
* tests/funcarr.prg
* tests/testhtml.prg
* tests/readhrb.prg
* tests/tstcolor.prg
* tests/gtxfnt.prg
* tests/devtest.prg
* tests/aliaslck.prg
* tests/stripem.prg
* tests/dynobj.prg
* tests/tb1.prg
* tests/round.prg
* tests/longstr.prg
* tests/testdyn.prg
* tests/testdyn1.prg
* tests/delimtst.prg
* tests/tstdspac.prg
* tests/version.prg
* tests/setkeys.prg
* tests/gtcolors.prg
* tests/destruct.prg
* tests/seconds.prg
* tests/gtkeys.prg
* tests/usrrdd/exarr.prg
* doc/en/diskspac.txt
* doc/en/string.txt
* doc/en/rdd.txt
* doc/en/hashes.txt
* doc/en/hb_apigt.txt
* doc/en/rddord.txt
* doc/en/hb_api.txt
* doc/en/hb_date.txt
* doc/en/math.txt
* doc/en/hb_vm.txt
* doc/en/treport.txt
* doc/en/terminal.txt
* doc/en/hb_apiln.txt
* doc/en/dir.txt
* doc/en/command.txt
* doc/en/rddmisc.txt
* doc/en/errsys.txt
* doc/en/nation.txt
* doc/en/var.txt
* doc/en/dbstrux.txt
* doc/en/datetime.txt
* doc/en/memo.txt
* doc/en/tgetlist.txt
* doc/en/tlabel.txt
* doc/en/1stread.txt
* doc/en/hb_set.txt
* doc/en/hb_compa.txt
* doc/en/hb_apier.txt
* doc/en/hbinet.txt
* doc/en/hb_macro.txt
* doc/en/array.txt
* doc/en/hb_apiit.txt
* doc/en/rdddb.txt
* doc/en/dbsdf.txt
* doc/en/hvm.txt
* doc/en/input.txt
* doc/en/dbdelim.txt
* doc/en/browse.txt
* doc/en/menu.txt
* doc/en/hb_apird.txt
* doc/en/hb_apifs.txt
* doc/en/file.txt
* doc/en/lang.txt
* doc/en/objfunc.txt
* doc/en/eval.txt
* doc/en/binnum.txt
* doc/en/tclass.txt
* doc/en/misc.txt
* doc/en/set.txt
* doc/en/readme.txt
* doc/man/harbour.1
* doc/man/hbmk2.1
* doc/man/hbpp.1
* doc/man/hbtest.1
* doc/man/hbrun.1
* examples/hbextern/hbextern.prg
* examples/pp/pp.c
* examples/pp/hbpragma.c
* examples/pp/hbppcore.c
* examples/pp/hbppcomp.c
* examples/pp/hbpptbl.c
* examples/pp/hbppdef.h
* examples/superlib/hbsuper.prg
* examples/hbsqlit2/hbsqlit2.ch
* examples/misc/mankala.prg
* examples/misc/guess.prg
* examples/rddado/adordd.prg
* examples/rddado/adordd.ch
* examples/hbapollo/apollo.ch
* examples/hbapollo/apollo.c
* examples/hbapollo/apollo1.prg
* examples/hbdoc2/gentpl.prg
* examples/hbdoc2/gentxt.prg
* examples/hbdoc2/tmplates.prg
* examples/hbdoc2/genxml.prg
* examples/hbdoc2/genhtml.prg
* examples/hbdoc2/hbdoc2.prg
* examples/hbdoc2/hbdoc2.ch
* examples/guestbk/guestbk.prg
* examples/httpsrv/uhttpd.ini
* examples/httpsrv/uhttpd.prg
* examples/httpsrv/cookie.prg
* examples/httpsrv/cgifunc.prg
* examples/httpsrv/session.prg
* examples/terminal/trm_cli.prg
* examples/terminal/terminal.prg
* examples/terminal/trm_srv.prg
* examples/terminal/trm_app.prg
* examples/hbbtree/hb_btree.h
* examples/hbbtree/hb_btree.ch
* examples/hbbtree/hb_btree.c
* examples/hbbtree/tbtree.prg
* examples/hscript/hscript.prg
* examples/hscript/dir.hs
* examples/hscript/multiply.hs
* examples/hscript/ugly.hs
* examples/hscript/hello.hs
* examples/gtwvw/hbole.h
* examples/gtwvw/wvwdraw.c
* examples/gtwvw/wvwmenu.c
* examples/gtwvw/gtwvw.c
* examples/gtwvw/wvwstbar.c
* examples/gtwvw/wvwcheck.c
* examples/gtwvw/wvwfuncs.c
* examples/gtwvw/wvwpush.c
* examples/gtwvw/wvwedit.c
* examples/gtwvw/wvwtbar.c
* examples/gtwvw/hbgtwvw.h
* Deleted 'www.' from harbour-project.org website name.
(www.harbour-project.org -> harbour-project.org)
520 lines
14 KiB
Plaintext
520 lines
14 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
*
|
|
* Copyright 2009 Pritpal Bedi <pritpal@vouchcac.com>
|
|
* http://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.
|
|
*
|
|
*/
|
|
//----------------------------------------------------------------------//
|
|
//----------------------------------------------------------------------//
|
|
//----------------------------------------------------------------------//
|
|
//
|
|
// Terminal Server Application
|
|
//
|
|
// Pritpal Bedi (pritpal@vouchcac.com)
|
|
// 13 Feb 2009
|
|
//
|
|
//----------------------------------------------------------------------//
|
|
//----------------------------------------------------------------------//
|
|
//----------------------------------------------------------------------//
|
|
|
|
#include "common.ch"
|
|
|
|
//#include "wvtwin.ch"
|
|
|
|
#define WSABASEERR 10000
|
|
#define WSAECONNABORTED (WSABASEERR+53)
|
|
#define WSAECONNRESET (WSABASEERR+54)
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
#define TOP t_[ 1 ]
|
|
#define LFT t_[ 2 ]
|
|
#define BTM t_[ 3 ]
|
|
#define RGT t_[ 4 ]
|
|
|
|
#define ENDBLOCK "|/END\|"
|
|
|
|
#define TIMER_RECEIVE 1001
|
|
#define TIMER_SEND 1002
|
|
#define TIMER_PING 1010
|
|
|
|
#define SND_SCREEN 1 // Through Timer Only
|
|
#define SND_CODEBLOCK 2 // Application
|
|
#define SND_CLOCKINFO 3
|
|
#define SND_CLOCKONOFF 4
|
|
#define SND_MUSIC 5
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
STATIC s_srvrSocket
|
|
STATIC s_commSocket
|
|
STATIC s_lSendingClient := .F.
|
|
STATIC s_mutexSend := hb_mutexCreate()
|
|
|
|
Function RmtSvrInitialize( cServerInfo, nTimeoutClient, nTimeRefresh )
|
|
Local lExit := .t.
|
|
|
|
s_srvrSocket := NIL
|
|
s_commSocket := NIL
|
|
|
|
DEFAULT nTimeoutClient TO 60 // 60 SECONDS
|
|
DEFAULT nTimeRefresh TO .5 // 0.5 SECONDS
|
|
|
|
nTimeRefresh := 0.1
|
|
|
|
if !empty( cServerInfo )
|
|
if RmtSvrInitAsServer( cServerInfo, @s_srvrSocket, nTimeOutClient*1000 )
|
|
|
|
if RmtSvrAcceptClient( s_srvrSocket, @s_commSocket )
|
|
// Very Important Factor 20-50 No more
|
|
//
|
|
Hb_INetTimeout( s_commSocket, 10 )
|
|
|
|
lExit := .f.
|
|
|
|
RmtSvrRunning( .t. )
|
|
|
|
hb_threadStart( @Thread_Receive(), 0.05 )
|
|
hb_threadStart( @Thread_Send() , nTimeRefresh )
|
|
hb_threadStart( @Thread_Ping() , 3 )
|
|
|
|
// Wvt_SetTimer( TIMER_RECEIVE, 50 ) // 50 ok 1/20 of a second
|
|
// Wvt_SetTimer( TIMER_SEND , nTimeRefresh*1000 )
|
|
// Wvt_SetTimer( TIMER_PING , 3000 )
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
if lExit
|
|
if s_srvrSocket != NIL
|
|
if Hb_INetErrorCode( s_srvrSocket ) == 0
|
|
Hb_InetClose( s_srvrSocket )
|
|
endif
|
|
endif
|
|
if s_commSocket != NIL
|
|
if Hb_INetErrorCode( s_commSocket ) == 0
|
|
Hb_InetClose( s_commSocket )
|
|
endif
|
|
endif
|
|
|
|
Hb_INetCleanUp()
|
|
endif
|
|
|
|
Return !( lExit )
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Static Function RmtSvrInitAsServer( cServerInfo, Socket, nTimeoutClient )
|
|
Local lRet := .f.
|
|
|
|
Hb_INetInit()
|
|
|
|
Socket := Hb_INetServer( val( cServerInfo ) )
|
|
if Hb_InetErrorCode( Socket ) == 0
|
|
lRet := .t.
|
|
endif
|
|
|
|
if lRet
|
|
// Wait for 1 minutes maximum : W A T C H INI Controlled
|
|
//
|
|
Hb_INetTimeout( Socket, nTimeoutClient )
|
|
TrmDebug( "SERVER: Connection Established!", hb_INetPort( Socket ) )
|
|
else
|
|
TrmDebug( "SERVER: Connection Failed" )
|
|
endif
|
|
|
|
Return lRet
|
|
|
|
//----------------------------------------------------------------------//
|
|
//
|
|
// Waits for 2 minutes each try
|
|
//
|
|
Static Function RmtSvrAcceptClient( Socket, pClientSocket )
|
|
Local lRet := .t.
|
|
// Local i := 0
|
|
|
|
Do While .t.
|
|
pClientSocket := Hb_InetAccept( Socket )
|
|
|
|
if pClientSocket != NIL
|
|
lRet := .t.
|
|
endif
|
|
|
|
exit
|
|
|
|
//TrmDebug( "SvrConnectClient()", i++, "TRY..." )
|
|
enddo
|
|
|
|
if lRet
|
|
TrmDebug( "CLIENT: Connection Established!", hb_INetPort( pClientSocket ) )
|
|
else
|
|
TrmDebug( "CLIENT: Connection TimedOut!" )
|
|
endif
|
|
|
|
Return .t.
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Function RmtSvrSendClient( nMode, xData )
|
|
Local cCurs, nError, nBytesSent, nBytesToSend, t_, cOdd, cEvn, cOdd0, cEvn0
|
|
Local lSendCurs := .f.
|
|
Local lSendScrn := .f.
|
|
Local cData := ""
|
|
|
|
static cCursor := " "
|
|
static cSOdd := " "
|
|
static cSEvn := " "
|
|
static n := 0
|
|
static nScreen := 0
|
|
|
|
n++
|
|
|
|
if RmtSvrRunning()
|
|
if !( s_lSendingClient )
|
|
s_lSendingClient := .t.
|
|
|
|
do case
|
|
case nMode == SND_SCREEN
|
|
cCurs := hb_ntos( Row() ) +";"+ ;
|
|
hb_ntos( Col() ) +";"+ ;
|
|
hb_ntos( Set( _SET_CURSOR ) ) +";"
|
|
|
|
if !( cCurs == cCursor )
|
|
lSendCurs := .t.
|
|
cCursor := cCurs
|
|
endif
|
|
|
|
t_:= xData
|
|
DEFAULT t_ TO { 0, 0, maxrow( .t. ), maxcol( .t. ) }
|
|
|
|
cOdd := ""
|
|
cEvn := ""
|
|
|
|
GETSCREENATTRIB( TOP,LFT,BTM,RGT,@cOdd,@cEvn )
|
|
|
|
if !( cSOdd == cOdd ) .or. !( cSEvn == cEvn )
|
|
lSendScrn := .t.
|
|
cSOdd := cOdd
|
|
cSEvn := cEvn
|
|
endif
|
|
|
|
if lSendScrn
|
|
nScreen++
|
|
|
|
cOdd0 := hb_zcompress( cOdd )
|
|
cEvn0 := hb_zcompress( cEvn )
|
|
|
|
cData := '<SCR>' +;
|
|
hb_ntos( TOP ) +';'+ hb_ntos( LFT ) +';'+ hb_ntos( BTM ) +';'+ hb_ntos( RGT ) +';'+;
|
|
hb_ntos( len( cOdd0 ) ) +';'+ ;
|
|
hb_ntos( len( cEvn0 ) ) +';'+ ;
|
|
'</E?>' +;
|
|
cOdd0 +;
|
|
cEvn0 +;
|
|
'</E?>' +;
|
|
'</SCR>' +;
|
|
'<CRS>' + cCurs + '</CRS>' +;
|
|
'<ID>' + hb_ntos( nScreen )+ '</ID>'
|
|
|
|
elseif lSendCurs
|
|
cData := '<CRS>'+ cCurs +'</CRS>'
|
|
|
|
endif
|
|
|
|
case nMode == SND_CODEBLOCK
|
|
cData := '<BLK>'+ xData +'</BLK>'
|
|
|
|
case nMode == SND_CLOCKINFO
|
|
cData := '<CLK_INFO>'+ xData +'</CLK_INFO>'
|
|
|
|
case nMode == SND_CLOCKONOFF
|
|
cData := '<CLK_ONOFF>'+ if( xData, 'TRUE','FALSE' ) +'</CLK_ONOFF>'
|
|
|
|
case nMode == SND_MUSIC
|
|
cData := '<MUSIC>'+ upper( xData ) +'</MUSIC>'
|
|
|
|
endcase
|
|
|
|
if len( cData ) > 0
|
|
cData += ENDBLOCK
|
|
nBytesToSend := len( cData )
|
|
nBytesSent := hb_INetSendAll( s_commSocket, cData, nBytesToSend )
|
|
|
|
if nBytesSent <> nBytesToSend
|
|
nError := hb_INetErrorCode( s_commSocket )
|
|
TrmDebug( n,'E','VouchServer - SvrSendClient : ', nError, nBytesSent, nBytesToSend )
|
|
|
|
do case
|
|
case ascan( { -2, WSAECONNABORTED, WSAECONNRESET }, nError ) > 0
|
|
TrmDebug( n,'Q','VouchServer - SvrSendClient : ', nError, nBytesSent, nBytesToSend )
|
|
DbCloseAll()
|
|
Quit
|
|
|
|
otherwise
|
|
|
|
endcase
|
|
endif
|
|
endif
|
|
|
|
s_lSendingClient := .f.
|
|
endif
|
|
endif
|
|
|
|
Return nil
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Static Function RmtSvrReceiveClient()
|
|
Local cKey, nBytes, nError
|
|
|
|
static lInProcess := .f.
|
|
|
|
if !lInProcess
|
|
if hb_INetDataReady( s_commSocket ) > 0
|
|
lInProcess := .t.
|
|
|
|
cKey := hb_INetRecvLine( s_commSocket, @nBytes )
|
|
|
|
if nBytes > 0
|
|
hb_KeyPut( Val( cKey ) )
|
|
|
|
elseif nBytes == 1
|
|
|
|
else
|
|
nError := hb_INetErrorCode( s_commSocket )
|
|
if ascan( { -2, WSAECONNABORTED, WSAECONNRESET }, nError ) > 0
|
|
TrmDebug( 'VouchAsServer - Quitting : Error =', hb_INetErrorCode( s_commSocket ), 'nBytes =', nBytes )
|
|
DbCloseAll()
|
|
Quit
|
|
endif
|
|
endif
|
|
|
|
lInProcess := .f.
|
|
endif
|
|
endif
|
|
|
|
Return nil
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Required as this receive all timer events
|
|
//
|
|
Function Wvt_Timer( wParam )
|
|
|
|
switch wParam
|
|
|
|
case TIMER_RECEIVE
|
|
RmtSvrReceiveClient()
|
|
exit
|
|
|
|
case TIMER_SEND
|
|
RmtSvrSendClient( 1, NIL )
|
|
exit
|
|
|
|
case TIMER_PING
|
|
if !( s_lSendingClient )
|
|
hb_INetSendAll( s_commSocket, ENDBLOCK )
|
|
endif
|
|
exit
|
|
|
|
end
|
|
|
|
Return 0
|
|
|
|
STATIC PROCEDURE Thread_Receive( nWait )
|
|
|
|
DO WHILE .T.
|
|
RmtSvrReceiveClient()
|
|
hb_idleSleep( nWait )
|
|
ENDDO
|
|
|
|
RETURN
|
|
|
|
STATIC PROCEDURE Thread_Send( nWait )
|
|
|
|
DO WHILE .T.
|
|
hb_mutexLock( s_mutexSend )
|
|
RmtSvrSendClient( 1, NIL )
|
|
hb_mutexUnlock( s_mutexSend )
|
|
hb_idleSleep( nWait )
|
|
ENDDO
|
|
|
|
RETURN
|
|
|
|
STATIC PROCEDURE Thread_Ping( nWait )
|
|
|
|
DO WHILE .T.
|
|
hb_mutexLock( s_mutexSend )
|
|
hb_INetSendAll( s_commSocket, ENDBLOCK )
|
|
hb_mutexUnlock( s_mutexSend )
|
|
hb_idleSleep( nWait )
|
|
ENDDO
|
|
|
|
RETURN
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Function RmtSvrSetInfo( cnInfo )
|
|
Local xInfo
|
|
|
|
static aInfo := { NIL,NIL,NIL }
|
|
|
|
if valtype( cnInfo ) == 'C' // To Retrieve it will be N
|
|
aInfo[ 1 ] := val( cnInfo ) // Port to Use
|
|
|
|
elseif valtype( cnInfo ) == 'N'
|
|
xInfo := aInfo[ cnInfo ]
|
|
|
|
endif
|
|
|
|
Return xInfo
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Function RmtSvrRunning( lYes )
|
|
Local sYes
|
|
static oYes := .f.
|
|
sYes := oYes
|
|
|
|
if valtype( lYes ) == 'L'
|
|
oYes := lYes
|
|
endif
|
|
|
|
return sYes
|
|
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Function TrmStr2A( cStr, cDel )
|
|
Local a_:={}, n
|
|
Local nlen
|
|
|
|
nLen := len( cDel )
|
|
|
|
do while .t.
|
|
if ( n := at( cDel, cStr ) ) == 0
|
|
exit
|
|
endif
|
|
|
|
aadd( a_, substr( cStr,1,n-1 ) )
|
|
|
|
cStr := substr( cStr,n+nLen )
|
|
enddo
|
|
|
|
Return a_
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Function TrmDebug( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 )
|
|
Local cDebug := ''
|
|
|
|
if p1 <> nil
|
|
cDebug += TrmXtoS( p1 )
|
|
endif
|
|
if p2 <> nil
|
|
cDebug += ' ' + TrmXtoS( p2 )
|
|
endif
|
|
if p3 <> nil
|
|
cDebug += ' ' + TrmXtoS( p3 )
|
|
endif
|
|
if p4 <> nil
|
|
cDebug += ' ' + TrmXtoS( p4 )
|
|
endif
|
|
if p5 <> nil
|
|
cDebug += ' ' + TrmXtoS( p5 )
|
|
endif
|
|
if p6 <> nil
|
|
cDebug += ' ' + TrmXtoS( p6 )
|
|
endif
|
|
if p7 <> nil
|
|
cDebug += ' ' + TrmXtoS( p7 )
|
|
endif
|
|
if p8 <> nil
|
|
cDebug += ' ' + TrmXtoS( p8 )
|
|
endif
|
|
if p9 <> nil
|
|
cDebug += ' ' + TrmXtoS( p9 )
|
|
endif
|
|
if p10 <> nil
|
|
cDebug += ' ' + TrmXtoS( p10 )
|
|
endif
|
|
|
|
#if defined( __PLATFORM__WINDOWS )
|
|
wapi_OutputDebugString( cDebug )
|
|
#endif
|
|
|
|
Return nil
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
FUNCTION TrmXtoS( xVar )
|
|
|
|
SWITCH ValType( xVar )
|
|
CASE "C"
|
|
RETURN xVar
|
|
CASE "N"
|
|
RETURN Str( xVar )
|
|
CASE "D"
|
|
RETURN DToC( xVar )
|
|
CASE "L"
|
|
RETURN iif( xVar, "T", "F" )
|
|
ENDSWITCH
|
|
|
|
RETURN "NIL"
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
Function TrmDummy()
|
|
Return nil
|
|
|
|
//----------------------------------------------------------------------//
|
|
|
|
STATIC PROCEDURE GETSCREENATTRIB( nT, nL, nB, nR, cOdd, cEvn )
|
|
LOCAL s := SaveScreen( nT, nL, nB, nR )
|
|
cOdd := CharOdd( s )
|
|
cEvn := CharEven( s )
|
|
RETURN
|