* contrib/libnf/dispc.c
+ ported to Harbour of FT_DISPFILE().
See also FT_DFSETUP() and FT_DFCLOSE().
This function permit browse for a file without loading it in memory.
This commit is contained in:
930
harbour/contrib/libnf/dispc.c
Normal file
930
harbour/contrib/libnf/dispc.c
Normal file
@@ -0,0 +1,930 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* File......: DISPC.C
|
||||
* Author....: Mike Taylor
|
||||
* CIS ID....: ?
|
||||
*
|
||||
* This is an original work by Mike Taylor and is placed in the
|
||||
* public domain.
|
||||
*
|
||||
* Modification history:
|
||||
* ---------------------
|
||||
*
|
||||
* Rev 1.7 29 Mar 2002 17:00:00 Walter Negro <anegro@overnet.com.ar>
|
||||
* Ported to Harbour
|
||||
*
|
||||
* Rev 1.6 01 Jan 1995 03:01:00 TED
|
||||
* Changed some prototypes to eliminate compiler warnings.
|
||||
*
|
||||
* Rev 1.5 14 Feb 1994 16:58:42 GLENN
|
||||
* Steve Tyrakowski and Kevin Maher modified to be CPMI-compliant.
|
||||
*
|
||||
* Rev 1.4 18 Nov 1991 02:20:20 GLENN
|
||||
* Mike fixed a bug in _ft_dfinit() related to allocating memory. Some
|
||||
* users had been reporting problems, but everyone who tested this patch
|
||||
* reported success.
|
||||
*
|
||||
* Rev 1.3 17 Aug 1991 15:25:46 GLENN
|
||||
* Don Caton fixed some spelling errors in the doc
|
||||
*
|
||||
* Rev 1.2 15 Aug 1991 23:08:14 GLENN
|
||||
* Forest Belt proofread/edited/cleaned up doc
|
||||
*
|
||||
* Rev 1.1 14 Jun 1991 19:53:42 GLENN
|
||||
* Minor edit to file header
|
||||
*
|
||||
* Rev 1.0 01 Apr 1991 01:02:46 GLENN
|
||||
* Nanforum Toolkit
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "hbdefs.h"
|
||||
#include "hbapi.h"
|
||||
#include "hbapifs.h"
|
||||
#include "hbapigt.h"
|
||||
|
||||
#include "fm.api"
|
||||
#include "inkey.ch"
|
||||
|
||||
#define OFF 0
|
||||
#define ON (!OFF)
|
||||
#define NO 0
|
||||
#define YES (!NO)
|
||||
#define OK 0
|
||||
#define K_STRING 0
|
||||
#define K_LIST (!K_STRING)
|
||||
|
||||
#define CR ((char) 13)
|
||||
#define LF ((char) 10)
|
||||
#define FEOF ((char) 26)
|
||||
|
||||
#define SEEK_END 2 /* file seek directions */
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_SET 0
|
||||
|
||||
#define READONLY 0 /* open file modes */
|
||||
#define WRITEONLY 1
|
||||
#define READWRITE 2
|
||||
|
||||
#define BUFFERSIZE 4096 /* maximum size of the file buffer */
|
||||
#define MAXLINE 255 /* default maximum size of a line */
|
||||
|
||||
#define TABSET 8
|
||||
|
||||
long buffoffset; /* offset into buffer of current line */
|
||||
long fsize; /* file size in bytes */
|
||||
int bufftop, buffbot; /* first and last character in buffer */
|
||||
int wintop, winbot; /* first and last character in window */
|
||||
int winrow, wincol; /* row and column of window highlight */
|
||||
int sline, eline; /* start and end line of window */
|
||||
int scol, ecol; /* start and end col of window */
|
||||
int height, width; /* height and width of window */
|
||||
int infile; /* input file handle */
|
||||
int maxlin; /* line size */
|
||||
int buffsize; /* buffer size */
|
||||
int hlight; /* highlight attribute */
|
||||
int norm; /* normal attribute */
|
||||
int kcount; /* number of keys in terminate key list*/
|
||||
int colinc; /* col increment amount */
|
||||
int brows; /* browse flag */
|
||||
char refresh; /* YES means refresh screen */
|
||||
char kstr[25]; /* terminate key string */
|
||||
int keylist[24]; /* terminate key list */
|
||||
int keytype; /* K_STRING or K_LIST */
|
||||
|
||||
int isallocated; /* if buffers were allocated */
|
||||
char *buffer; /* file buffer pointer */
|
||||
char *lbuff; /* line buffer pointer */
|
||||
char *vseg; /* video segment variable */
|
||||
|
||||
/* prototypes */
|
||||
|
||||
|
||||
static int keyin(void);
|
||||
static void chattr(int x, int y, int len, int attr);
|
||||
static long getblock(long offset);
|
||||
static void buff_align(void);
|
||||
static void win_align(void);
|
||||
static void disp_update(int offset);
|
||||
static void windown(void);
|
||||
static void winup(void);
|
||||
static void linedown(void);
|
||||
static void lineup(void);
|
||||
static void filetop(void);
|
||||
static void filebot(void);
|
||||
static void strcpyn(char *dest, const char *source, int len);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* chattr() replace the color attribute with a new one starting at
|
||||
* location x, y and going for length len.
|
||||
*
|
||||
*/
|
||||
|
||||
static void chattr(int x, int y, int len, int attr)
|
||||
{
|
||||
int i;
|
||||
char *vmem;
|
||||
|
||||
vmem = vseg + (y * (width + 1) * 2) + (x * 2) + 1;
|
||||
/* calc the screen memory coord */
|
||||
|
||||
for (i = 0; i <= len; i++, vmem += 2) /* write the new attribute value */
|
||||
*vmem = (char) attr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* function getblock() reads the text file and returns the a block.
|
||||
* the variables offset and buffsize tell it where to start reading and
|
||||
* how many bytes to try to read. if the block read in would not fill
|
||||
* the buffer then the offset is adjusted so that the start or end of
|
||||
* of the file is positioned at the head or tail of the buffer.
|
||||
*
|
||||
* it returns the offset into the file of the first byte of the buffer.
|
||||
*
|
||||
*/
|
||||
|
||||
static long getblock(long offset)
|
||||
{
|
||||
/*
|
||||
set the file pointer to the proper offset
|
||||
and if an error occured then check to see
|
||||
if a positive offset was requested, if so
|
||||
then set the pointer to the offset from
|
||||
the end of the file, otherwise set it from
|
||||
the beginning of the file.
|
||||
*/
|
||||
|
||||
hb_fsSeek( infile, offset, SEEK_SET );
|
||||
|
||||
/* read in the file and set the buffer bottom variable equal */
|
||||
/* to the number of bytes actually read in. */
|
||||
|
||||
buffbot = hb_fsReadLarge( infile, buffer, buffsize );
|
||||
|
||||
/* if a full buffer's worth was not read in, make it full. */
|
||||
|
||||
if (( buffbot != buffsize ) && ( fsize > buffsize ))
|
||||
{
|
||||
if ( offset > 0 )
|
||||
hb_fsSeek( infile, (long) -buffsize, SEEK_END );
|
||||
else
|
||||
hb_fsSeek( infile, (long) buffsize, SEEK_SET );
|
||||
|
||||
buffbot = hb_fsReadLarge( infile, buffer, buffsize );
|
||||
}
|
||||
|
||||
/* return the actual file position */
|
||||
|
||||
return( hb_fsSeek( infile, 0L, SEEK_CUR ) - buffbot);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* buff_align makes sure the buffer top and bottom variables point
|
||||
* to actual complete lines of text.
|
||||
*
|
||||
*/
|
||||
|
||||
static void buff_align()
|
||||
{
|
||||
int i;
|
||||
|
||||
bufftop = 0;
|
||||
buffbot = buffsize;
|
||||
|
||||
if ( buffoffset != 0L ) /* if the buffoffset is otherthan 0 */
|
||||
{
|
||||
i = bufftop; /* start at the top of the file and scan */
|
||||
/* forward until a CR is reached. */
|
||||
|
||||
while (( buffer[i] != CR ) && ( i < buffbot ))
|
||||
i++;
|
||||
|
||||
bufftop = i + 2;
|
||||
}
|
||||
|
||||
/* if the buffer offset is not a complete */
|
||||
/* buffer's length away from the file end */
|
||||
|
||||
if ( buffoffset + ((long) buffbot) != fsize )
|
||||
{
|
||||
/*
|
||||
if the file position of the last byte
|
||||
of the buffer would end up past the
|
||||
end of the file, then the buffer does
|
||||
contain a complete buffer full and the
|
||||
buffer end pointer needs to be set to
|
||||
the last character of the file.
|
||||
*/
|
||||
|
||||
if ( buffoffset + ((long) buffbot) > fsize )
|
||||
buffbot = (int) (fsize - buffoffset);
|
||||
|
||||
i = buffbot; /* point the end of the buffer to a valid */
|
||||
/* complete text line. */
|
||||
|
||||
while (( buffer[i] != CR ) && ( i > bufftop ))
|
||||
i--;
|
||||
|
||||
buffbot = i + 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* win_align takes the value for wintop and then figures out where
|
||||
* winbot would be. if winbot would extend past the end of the
|
||||
* buffer, then the top of the window is adjusted to ensure that a full
|
||||
* screen of text will appear. This simplifies the cursor routines.
|
||||
*
|
||||
*/
|
||||
|
||||
static void win_align()
|
||||
{
|
||||
int i;
|
||||
|
||||
winbot = wintop; /* find out if there is enough text for */
|
||||
i = 0; /* full window. */
|
||||
|
||||
while (( winbot < buffbot ) && ( i < height ))
|
||||
{
|
||||
if ( buffer[winbot] == CR )
|
||||
i++;
|
||||
winbot++;
|
||||
}
|
||||
|
||||
if ( i < height ) /* if there is not a full window, */
|
||||
{
|
||||
/* then retrofit winbot to the end of a line */
|
||||
while ( buffer[winbot] != LF && winbot > bufftop)
|
||||
winbot--;
|
||||
|
||||
wintop = winbot;
|
||||
i = 0; /* and setup wintop */
|
||||
|
||||
while (( wintop > bufftop ) && ( i <= height ))
|
||||
{
|
||||
if ( buffer[wintop] == LF )
|
||||
i++;
|
||||
wintop--;
|
||||
}
|
||||
|
||||
if ( wintop != bufftop )
|
||||
wintop += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* this routine displays the actual text in the window. This is done
|
||||
* by taking each line and placing it in a string. the screen line
|
||||
* is then taken from the appropriate group of characters in the string.
|
||||
* this allows a window to page left-right across the buffer without
|
||||
* having to use any complex algorithm to calc the needed chars.
|
||||
*
|
||||
*/
|
||||
|
||||
static void disp_update(int offset)
|
||||
{
|
||||
int line, col, pos, i;
|
||||
char *vmem;
|
||||
|
||||
|
||||
refresh = NO;
|
||||
line = 0;
|
||||
|
||||
while ( line < height )
|
||||
{
|
||||
/*
|
||||
calculate the initial position, this save execution
|
||||
time because each column is considered as a offset
|
||||
from the line start
|
||||
*/
|
||||
|
||||
pos = (line * (width + 1) * 2);
|
||||
|
||||
/* copy string to temp buffer */
|
||||
|
||||
for (i = 0; buffer[offset] != CR && offset <= winbot; offset++)
|
||||
{
|
||||
if ( i <= maxlin )
|
||||
{
|
||||
if (buffer[offset] == '\t') /* check for a tab */
|
||||
{
|
||||
lbuff[i++] = ' '; /* pad with spaces */
|
||||
while (i % TABSET && i <= maxlin) /* until tab stop */
|
||||
lbuff[i++] = ' '; /* is reached or EOL */
|
||||
}
|
||||
else lbuff[i++] = buffer[offset];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (; i <= maxlin; i++) /* fill out with spaces */
|
||||
lbuff[i] = ' ';
|
||||
|
||||
/* place the proper characters onto the screen */
|
||||
|
||||
for (i = wincol, col = 0; col <= width; col++)
|
||||
{
|
||||
vmem = vseg + pos + (col * 2);
|
||||
|
||||
*vmem = lbuff[i++];
|
||||
}
|
||||
|
||||
line += 1;
|
||||
offset += 2;
|
||||
}
|
||||
hb_gtRest( sline, scol, eline, ecol, vseg );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* move the window pointers so that a new window's worth of information
|
||||
* is visible. it adjusts the pointers within the buffer and if necessary
|
||||
* it calls the getblock function to load in a new buffer
|
||||
*
|
||||
*/
|
||||
|
||||
static void winup()
|
||||
{
|
||||
int k;
|
||||
long i, j;
|
||||
|
||||
refresh = YES;
|
||||
k = wintop - 3;
|
||||
|
||||
while (( buffer[k] != CR ) && ( k > bufftop ))
|
||||
k--;
|
||||
|
||||
if ( k >= bufftop )
|
||||
{
|
||||
if (buffer[k] == CR) k += 2;
|
||||
|
||||
wintop = k;
|
||||
k = winbot - 3;
|
||||
|
||||
while ( buffer[k] != CR )
|
||||
k--;
|
||||
|
||||
winbot = k + 2;
|
||||
}
|
||||
else
|
||||
if ( ((long) bufftop) + buffoffset > 0 && fsize > buffsize )
|
||||
{
|
||||
i = buffoffset + wintop;
|
||||
j = buffoffset - ((long) (buffsize / 2));
|
||||
|
||||
if ( j < 0 )
|
||||
j = 0;
|
||||
|
||||
buffoffset = getblock(j);
|
||||
wintop = ((int) (i - buffoffset));
|
||||
|
||||
buff_align();
|
||||
win_align();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* move the window pointers so that a new window's worth of information
|
||||
* is visible. it adjusts the pointers within the buffer and if necessary
|
||||
* it calls the getblock function to load in a new buffer
|
||||
*
|
||||
*/
|
||||
|
||||
static void windown()
|
||||
{
|
||||
int k;
|
||||
long i, j;
|
||||
|
||||
refresh = YES;
|
||||
k = winbot;
|
||||
|
||||
while (( buffer[k] != CR ) && ( k <= buffbot ))
|
||||
k++;
|
||||
k += 2;
|
||||
|
||||
if ( k <= buffbot )
|
||||
{
|
||||
winbot = k;
|
||||
k = wintop;
|
||||
|
||||
while ( buffer[k] != CR )
|
||||
k++;
|
||||
wintop = k + 2;
|
||||
}
|
||||
else
|
||||
if ( (((long) buffbot) + buffoffset) < fsize && fsize > buffsize)
|
||||
{
|
||||
i = buffoffset + wintop;
|
||||
j = i;
|
||||
|
||||
if ( j > fsize )
|
||||
j = fsize - ((long) buffsize);
|
||||
|
||||
buffoffset = getblock(j);
|
||||
|
||||
if ( i < buffoffset )
|
||||
wintop = 0;
|
||||
else
|
||||
wintop = ((int) (i - buffoffset));
|
||||
|
||||
buff_align();
|
||||
win_align();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* move the cursor one line down */
|
||||
|
||||
static void linedown()
|
||||
{
|
||||
if ( winrow < eline ) /* if cursor not at last line */
|
||||
winrow += 1;
|
||||
else /* otherwise adjust the window top variable */
|
||||
windown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* move the cursor one line up */
|
||||
|
||||
static void lineup()
|
||||
{
|
||||
if ( winrow > sline )
|
||||
winrow -= 1;
|
||||
else
|
||||
winup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* go to the top of the file */
|
||||
|
||||
static void filetop()
|
||||
{
|
||||
if ( buffoffset != 0 )
|
||||
{
|
||||
buffoffset = getblock(0L);
|
||||
|
||||
buff_align();
|
||||
}
|
||||
|
||||
refresh = YES;
|
||||
wintop = (int) buffoffset;
|
||||
winrow = sline;
|
||||
wincol = 0;
|
||||
|
||||
win_align();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* goto the bottom of the file */
|
||||
|
||||
static void filebot()
|
||||
{
|
||||
if ( (((long) buffbot) + buffoffset) < fsize && fsize > buffsize )
|
||||
{
|
||||
buffoffset = getblock(fsize + 1);
|
||||
|
||||
buff_align();
|
||||
}
|
||||
|
||||
refresh = YES;
|
||||
wintop = buffbot - 3;
|
||||
winrow = eline;
|
||||
wincol = 0;
|
||||
|
||||
win_align();
|
||||
}
|
||||
|
||||
|
||||
HB_FUNC( _FT_DFINIT )
|
||||
{
|
||||
int rval, i, j;
|
||||
USHORT uiSize;
|
||||
|
||||
rval = 0;
|
||||
|
||||
sline = hb_parni(2); /* top row of window */
|
||||
scol = hb_parni(3); /* left col */
|
||||
eline = hb_parni(4); /* bottom row */
|
||||
ecol = hb_parni(5); /* right col */
|
||||
|
||||
width = ecol - scol; /* calc width of window */
|
||||
height = eline - sline + 1; /* calc height of window */
|
||||
|
||||
hb_gtRectSize( sline, scol, eline, ecol, &uiSize );
|
||||
vseg = (char * ) hb_xalloc( uiSize );
|
||||
if (vseg != NULL)
|
||||
hb_gtSave( sline, scol, eline, ecol, vseg );
|
||||
|
||||
maxlin = hb_parni(12);
|
||||
buffsize = hb_parni(13); /* yes - load value */
|
||||
|
||||
buffer = hb_xalloc(buffsize); /* allocate memory */
|
||||
lbuff = hb_xalloc(maxlin + 1); /* for buffers */
|
||||
|
||||
|
||||
isallocated = !(buffer == NULL || lbuff == NULL || vseg == NULL);
|
||||
/* memory allocated? */
|
||||
if (isallocated == FALSE)
|
||||
{
|
||||
rval = 8; /* return error code 8 (memory) */
|
||||
if (buffer != NULL) hb_xfree(buffer);
|
||||
if (lbuff != NULL) hb_xfree(lbuff);
|
||||
if (vseg != NULL) hb_xfree(vseg);
|
||||
}
|
||||
else /* get parameters */
|
||||
{
|
||||
infile = hb_parni(1); /* file handle */
|
||||
j = hb_parni(6); /* starting line value */
|
||||
norm = hb_parni(7); /* normal color attribute */
|
||||
hlight = hb_parni(8); /* highlight color attribute */
|
||||
|
||||
if ((hb_parinfo(9) && 512) == 512) /* if array */
|
||||
{
|
||||
keytype = K_LIST;
|
||||
kcount = hb_parinfa( 9, 0 );
|
||||
if (kcount > 24)
|
||||
kcount = 24;
|
||||
for (i = 1; i <= kcount; i++)
|
||||
keylist[i - 1] = hb_parni( 9, i ); /* get exit key list */
|
||||
}
|
||||
else
|
||||
{
|
||||
keytype = K_STRING;
|
||||
kcount = hb_parclen( 9 );
|
||||
if (kcount > 24)
|
||||
kcount = 24;
|
||||
strcpyn(kstr, hb_parc(9), kcount); /* get exit key string */
|
||||
}
|
||||
|
||||
brows = hb_parl(10); /* get browse flag */
|
||||
|
||||
colinc = hb_parni(11); /* column skip value */
|
||||
|
||||
|
||||
|
||||
bufftop = 0; /* init buffer top pointer */
|
||||
buffbot = buffsize; /* init buffer bottom pointer */
|
||||
buffoffset = 0; /* curr line offset into buffer */
|
||||
winrow = sline; /* init window row */
|
||||
wincol = 0; /* init window col */
|
||||
wintop = 0; /* init window top pointer */
|
||||
winbot = 0; /* init window bottom pointer */
|
||||
|
||||
|
||||
|
||||
/* get file size */
|
||||
|
||||
fsize = hb_fsSeek( infile, 0L, SEEK_END ) - 1;
|
||||
|
||||
/* get the first block */
|
||||
|
||||
hb_fsSeek( infile, 0L, SEEK_SET );
|
||||
|
||||
/* if block less than buffsize */
|
||||
|
||||
if ( fsize < ((long) buffbot) )
|
||||
buffbot = (int) fsize; /* then set buffer bottom */
|
||||
|
||||
/* set the current lines buffer offset pointer */
|
||||
|
||||
buffoffset = getblock((long) bufftop);
|
||||
|
||||
/* align buffer and window pointer to valid values */
|
||||
|
||||
buff_align();
|
||||
win_align();
|
||||
|
||||
/* point line pointer to line passed by caller */
|
||||
|
||||
for (i = 1; i < j; i++)
|
||||
linedown();
|
||||
|
||||
hb_gtRest( sline, scol, eline, ecol, vseg );
|
||||
|
||||
}
|
||||
|
||||
hb_retni(rval);
|
||||
}
|
||||
|
||||
HB_FUNC ( _FT_DFCLOS )
|
||||
{
|
||||
if (isallocated == TRUE)
|
||||
{
|
||||
if (buffer != NULL) hb_xfree(buffer); /* free up allocated buffer memory */
|
||||
if (lbuff != NULL) hb_xfree(lbuff);
|
||||
if (vseg != NULL) hb_xfree(vseg);
|
||||
}
|
||||
}
|
||||
|
||||
/* $DOC$
|
||||
* $FUNCNAME$
|
||||
* FT_DISPFILE()
|
||||
* $CATEGORY$
|
||||
* File I/O
|
||||
* $ONELINER$
|
||||
* Browse a text file
|
||||
* $SYNTAX$
|
||||
* FT_DISPFILE() -> cExitkey
|
||||
* $ARGUMENTS$
|
||||
* None
|
||||
* $RETURNS$
|
||||
* The ASCII keystroke that terminated FT_DISPFILE()
|
||||
* $DESCRIPTION$
|
||||
* This routine displays a text file within a defined window using as
|
||||
* little memory as possible. The text file to display has to be
|
||||
* present or an error value of 0 is returned (as a character.)
|
||||
*
|
||||
* Assumptions: The routine assumes that all lines are terminated
|
||||
* with a CR/LF sequence (0x0d and 0x0a).
|
||||
*
|
||||
* Note: Make sure you allocate a buffer large enough to hold
|
||||
* enough data for the number of lines that you have
|
||||
* in the window. Use the following formula as a
|
||||
* guideline - buffer size = (# of line) + 1 * RMargin
|
||||
* this is the smallest you should make the buffer and
|
||||
* for normal use I recommend 4096 bytes.
|
||||
*
|
||||
* Cursor Keys: Up, Down - moves the highlight line
|
||||
* Left, Right - moves the window over nColSkip col's
|
||||
* Home - moves the window to the far left
|
||||
* End - moves the window to the nRMargin column
|
||||
* PgUp, PgDn - moves the highlight one page
|
||||
* Ctrl-PgUp - moves the highlight to the file top
|
||||
* Ctrl-PgDn - moves the highlight to the file bottom
|
||||
* Ctrl-Right - moves the window 16 col's to the right
|
||||
* Ctrl-Left - moves the window 16 col's to the left
|
||||
*
|
||||
* Esc, Return - terminates the function
|
||||
*
|
||||
* All other keys are ignored unless they are specified
|
||||
* within cExitKeys parameter. This list will tell the
|
||||
* routine what keys terminate the function. Special
|
||||
* keys must be passed by a unique value and that value
|
||||
* can be found by looking in the keys.h file.
|
||||
* $EXAMPLES$
|
||||
* @ 4,9 TO 11,71
|
||||
*
|
||||
* FT_DFSETUP("test.txt", 5, 10, 10, 70, 1, 7, 15,;
|
||||
* "AaBb" + Chr(143), .T., 5, 132, 4096)
|
||||
*
|
||||
* cKey = FT_DISPFILE()
|
||||
*
|
||||
* FT_DFCLOSE()
|
||||
*
|
||||
* @ 20,0 SAY "Key that terminated FT_DISPFILE() was: " + '[' + cKey + ']'
|
||||
* $SEEALSO$
|
||||
* FT_DFSETUP() FT_DFCLOSE()
|
||||
* $END$
|
||||
*/
|
||||
|
||||
HB_FUNC( FT_DISPFILE )
|
||||
{
|
||||
int i, done;
|
||||
char rval[2];
|
||||
|
||||
int ch;
|
||||
|
||||
|
||||
/* make sure buffers were allocated and file was opened */
|
||||
if (isallocated == TRUE && infile > 0)
|
||||
{
|
||||
done = NO;
|
||||
refresh = YES;
|
||||
|
||||
/* draw inside of window with normal color attribute */
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
chattr(0, i, width, norm);
|
||||
|
||||
hb_gtRest( sline, scol, eline, ecol, vseg );
|
||||
|
||||
/* main processing loop -- terminated by user key press */
|
||||
|
||||
do
|
||||
{
|
||||
if ( refresh == YES ) /* redraw window contents? */
|
||||
disp_update(wintop);
|
||||
|
||||
hb_gtRest( sline, scol, eline, ecol, vseg );
|
||||
|
||||
/* if not browse, highlight the current line */
|
||||
|
||||
if ( brows == NO )
|
||||
chattr(0, winrow - sline, width, hlight);
|
||||
|
||||
hb_gtRest( sline, scol, eline, ecol, vseg );
|
||||
|
||||
hb_gtSetPos( winrow, scol );
|
||||
|
||||
ch = keyin(); /* get user key press */
|
||||
|
||||
/* if not browse, then un-highlight current line */
|
||||
|
||||
if ( brows == NO )
|
||||
chattr(0, winrow - sline, width, norm);
|
||||
|
||||
hb_gtRest( sline, scol, eline, ecol, vseg );
|
||||
|
||||
/* figure out what the user wants to do */
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case K_DOWN : if ( brows == YES ) /* if browse flag */
|
||||
winrow = eline; /* is set, force */
|
||||
/* active line to */
|
||||
linedown(); /* be last line */
|
||||
break;
|
||||
|
||||
case K_UP : if ( brows == YES ) /* if browse flag */
|
||||
winrow = sline; /* is set, force */
|
||||
/* active line to */
|
||||
lineup(); /* be first line */
|
||||
break;
|
||||
|
||||
case K_LEFT : wincol -= colinc; /* move cursor */
|
||||
refresh = YES; /* to the left */
|
||||
|
||||
if ( wincol < 0 )
|
||||
wincol = 0;
|
||||
|
||||
break;
|
||||
|
||||
case K_RIGHT : wincol += colinc; /* move cursor */
|
||||
refresh = YES; /* to the right */
|
||||
|
||||
if ( wincol > (maxlin - width) )
|
||||
wincol = maxlin - width;
|
||||
|
||||
break;
|
||||
|
||||
case K_HOME : wincol = 0; /* move cursor */
|
||||
refresh = YES; /* to first col */
|
||||
|
||||
break;
|
||||
|
||||
/* move cursor to last col */
|
||||
|
||||
case K_END : wincol = maxlin - width;
|
||||
refresh = YES;
|
||||
|
||||
break;
|
||||
|
||||
case K_CTRL_LEFT : wincol -= 16; /* move cursor */
|
||||
refresh = YES; /* 16 col to left */
|
||||
|
||||
if ( wincol < 0 )
|
||||
wincol = 0;
|
||||
|
||||
break;
|
||||
|
||||
case K_CTRL_RIGHT : wincol += 16; /* move cursor */
|
||||
refresh = YES; /* 16 col to right */
|
||||
|
||||
if ( wincol > (maxlin - width) )
|
||||
wincol = maxlin - width;
|
||||
|
||||
break;
|
||||
|
||||
case K_PGUP : for (i = 0; i < height; i++) /* move window */
|
||||
winup(); /* up one page */
|
||||
|
||||
break;
|
||||
|
||||
case K_PGDN : for (i = 0; i < height; i++) /* move window */
|
||||
windown(); /* down 1 page */
|
||||
|
||||
break;
|
||||
|
||||
case K_CTRL_PGUP : filetop(); /* move cursor to */
|
||||
break; /* to top of file */
|
||||
|
||||
case K_CTRL_PGDN : filebot(); /* move cursor to */
|
||||
break; /* to bot of file */
|
||||
|
||||
case K_ENTER : done = YES; /* carriage return */
|
||||
break; /* terminates */
|
||||
|
||||
case K_ESC : done = YES; /* escape key */
|
||||
break; /* terminates */
|
||||
|
||||
/* scan key list and see if key pressed is there */
|
||||
|
||||
default : if (keytype == K_STRING)
|
||||
{
|
||||
for (i = 0; i <= kcount; i++)
|
||||
if ((ch > 0) && (ch < 256))
|
||||
if ( (int) kstr[i] == ch )
|
||||
done = YES;
|
||||
break; /* if so terminate */
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < kcount; i++)
|
||||
if ( keylist[i] == ch )
|
||||
done = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while ( done == NO );
|
||||
}
|
||||
else
|
||||
ch = 0;
|
||||
|
||||
|
||||
/* store the key pressed as a character to be returned */
|
||||
|
||||
/* return key value to caller */
|
||||
|
||||
if (keytype == K_STRING)
|
||||
{
|
||||
rval[0] = (char) ch;
|
||||
rval[1] = '\0';
|
||||
hb_retc( rval );
|
||||
}
|
||||
else
|
||||
hb_retni( ch );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* keyin() gets the next key typed and does any translation needed.
|
||||
* Some keys are converted to a common name - like the up arrow is
|
||||
* converted to the UP value which also is the Ctrl-E value. This
|
||||
* allows the Wordstar-like control keys to be used. Only extended
|
||||
* keys are translated - the values of the defines were chosen to
|
||||
* match up with the non-extended key codes.
|
||||
*
|
||||
*/
|
||||
|
||||
static int keyin()
|
||||
{
|
||||
int ch;
|
||||
|
||||
|
||||
ch = 0;
|
||||
while ( ch == 0x00 ) /* check to see if it's extended */
|
||||
{
|
||||
ch = hb_inkeyTranslate( hb_gtReadKey( 0 ), 0);
|
||||
if (ch == 257) /* error compiling with bcc55 */
|
||||
ch = 27; /* ESC with CapsLock ON = 257, with CapsLock OFF = 27 */
|
||||
hb_idleState();
|
||||
}
|
||||
|
||||
|
||||
return ( ch );
|
||||
}
|
||||
|
||||
|
||||
static void strcpyn( char *dest, const char *source, int len )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
dest[i] = source[i];
|
||||
|
||||
dest[len+1] = 0x00;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user