home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
ce331src.arj
/
BASIC.C
next >
Wrap
C/C++ Source or Header
|
1991-03-10
|
11KB
|
507 lines
/*
* B A S I C . C
*
* purpose:
* The routines in this file move the cursor around on the screen. They
* compute a new value for the cursor, then adjust dot. The display code
* always updates the cursor location, so only moves between lines, or
* functions that adjust the top line in the window and invalidate the
* framing, are hard.
*/
#include <stdio.h> /* Turbo C++ verison 1.0 */
#include <dos.h>
#include <pdefs.h> /* PforCe version 1.05 (includes jwg.h) */
#include <pf_ansi.h>
#include "struct.h"
#include "def.h"
#include "protos.h"
/**
* Move the cursor to the beginning of the current line
*/
int GotoBOL(f, n)
int f, n;
{
curwp->w_doto = 0;
return(TRUE);
}
/**
* Move the cursor backwards by "n" characters. If "n" is less than zero call
* "ForwChar" to actually do the move. Otherwise, compute the new cursor
* location. Error if you try and move out of the buffer. Set the flag if the
* line pointer for dot changes.
*/
int BackChar(f, n)
int f;
int n;
{
LINE *lp;
if (n < 0)
return(ForwChar(f, -n));
while (n--)
{
if (curwp->w_doto == 0)
{
if ((lp = lback(curwp->w_dotp)) == curbp->b_linep)
return(FALSE);
curwp->w_dotp = lp;
curwp->w_doto = llength(lp);
curwp->w_flag |= WFMOVE;
}
else
curwp->w_doto--;
}
return(TRUE);
}
/**
* Move the cursor to the end of the current line
*/
int GotoEOL(f, n)
int f, n;
{
curwp->w_doto = llength(curwp->w_dotp);
return(TRUE);
}
/**
* Move the cursor forward by "n" characters. If "n" is less than zero call
* "BackChar" to actually do the move. Otherwise, compute the new cursor
* location, and move dot. Error if you try and move out of the buffer. Set
* the flag if the line pointer for dot changes.
*/
int ForwChar(f, n)
int f;
int n;
{
if (n < 0)
return(BackChar(f, -n));
while (n--)
{
if (curwp->w_doto == llength(curwp->w_dotp))
{
if (curwp->w_dotp == curbp->b_linep)
return(FALSE);
curwp->w_dotp = lforw(curwp->w_dotp);
curwp->w_doto = 0;
curwp->w_flag |= WFMOVE;
}
else
curwp->w_doto++;
}
return(TRUE);
}
/**
* Move to a particular line (arg n must be positive for this to do anything)
*/
int GotoLine(f, n)
int f, n;
{
int status;
char arg[NSTRING]; /* buffer to hold argument */
/* get an argument if one doesn't exist */
if (f == FALSE)
{
if ((status = MlReply("Line to goto: ", arg, NSTRING)) != TRUE)
return(status);
n = cvtatoi(arg);
}
if (n < 1) /* if a bogus argument, then leave */
return(FALSE);
/* first, we go to the start of the buffer */
curwp->w_dotp = lforw(curbp->b_linep);
curwp->w_doto = 0;
return(ForwLine(f, n - 1));
}
/**
* Goto the beginning of the buffer. Massive adjustment of dot. This is
* considered to be hard motion; it really isn't if the original value of
* dot is the same as the new value.
*/
int GotoBOB(f, n)
int f, n;
{
curwp->w_dotp = lforw(curbp->b_linep);
curwp->w_doto = 0;
curwp->w_flag |= WFHARD;
return(TRUE);
}
/**
* Move to the end of the buffer. Dot is always put at the end of the file.
* The standard screen code does most of the hard parts of Update.
*/
int GotoEOB(f, n)
int f, n;
{
curwp->w_dotp = curbp->b_linep;
curwp->w_doto = 0;
curwp->w_flag |= WFHARD;
return(TRUE);
}
/**
* Move forward by full lines. If the number of lines to move is less than
* zero, call the backward line function to actually do it. The last command
* controls how the goal column is set. No errors are possible.
*/
int ForwLine(f, n)
int f, n;
{
LINE *dlp;
if (n < 0)
return(BackLine(f, -n));
/* if we are on the last line as we start, fail the command */
if (curwp->w_dotp == curbp->b_linep)
return(FALSE);
/* if the last command was not a line move, reset the goal column */
if (!(lastflag & CFLMOV))
curgoal = GetCurCol(FALSE);
/* flag this command as a line move */
thisflag |= CFLMOV;
/* and move the point down */
dlp = curwp->w_dotp;
while (n-- && dlp != curbp->b_linep)
dlp = lforw(dlp);
/* resetting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = GetGoal(dlp);
curwp->w_flag |= WFMOVE;
return(TRUE);
}
/**
* This function is like "ForwLine", but goes backward. The scheme is exactly
* the same. Check for arguments that are less than zero and call your
* alternate. Figure out the new line and call "movedot" to perform the
* motion. No errors are possible.
*/
int BackLine(f, n)
int f, n;
{
LINE *dlp;
if (n < 0)
return(ForwLine(f, -n));
/* if we are on the last line as we start, fail the command */
if (lback(curwp->w_dotp) == curbp->b_linep)
return(FALSE);
/* if the last command was not a line move, reset the goal column */
if (!(lastflag & CFLMOV))
curgoal = GetCurCol(FALSE);
/* flag this command as a line move */
thisflag |= CFLMOV;
/* and move the point up */
dlp = curwp->w_dotp;
while (n-- && lback(dlp) != curbp->b_linep)
dlp = lback(dlp);
/* resetting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = GetGoal(dlp);
curwp->w_flag |= WFMOVE;
return(TRUE);
}
/**
* This routine, given a pointer to a LINE, and the current cursor goal
* column, returns the best choice for the offset. Used by ForwLine() and
* BackLine().
*/
int GetGoal(dlp)
LINE *dlp;
{
int c;
int col;
int newcol;
int dbo;
col = 0;
dbo = 0;
while (dbo != llength(dlp))
{
c = lgetc(dlp, dbo);
newcol = col;
if (c == '\t')
newcol += -(newcol % tabsize) + (tabsize - 1);
else if (c < 0x20 || c == 0x7f)
++newcol;
++newcol;
if (newcol > curgoal)
break;
col = newcol;
++dbo;
}
return(dbo);
}
/**
* Scroll forward by a specified number of lines, or by a full page if no
* argument. The "2" in the arithmetic on the window size is the overlap.
* Because this zaps the top line in the display window, we have to do a hard
* Update.
*/
int ForwPage(f, n)
int f;
int n;
{
LINE *lp;
if (f == FALSE)
{
n = curwp->w_ntrows - 2; /* default scroll */
if (n <= 0) /* forget the overlap if tiny window */
n = 1;
}
else if (n < 0)
return(BackPage(f, -n));
lp = curwp->w_linep;
while (n-- && lp != curbp->b_linep)
lp = lforw(lp);
curwp->w_linep = lp;
curwp->w_dotp = lp;
curwp->w_doto = 0;
curwp->w_flag |= WFHARD;
return(TRUE);
}
/**
* This command is like "ForwPage", but it goes backward. The "2", like
* above, is the overlap between the two windows. We do a hard Update for
* exactly the same reason.
*/
int BackPage(f, n)
int f;
int n;
{
LINE *lp;
if (f == FALSE)
{
n = curwp->w_ntrows - 2; /* default scroll */
if (n <= 0) /* don't blow up if the window is tiny */
n = 1;
}
else if (n < 0)
return(ForwPage(f, -n));
lp = curwp->w_linep;
while (n-- && lback(lp) != curbp->b_linep)
lp = lback(lp);
curwp->w_linep = lp;
curwp->w_dotp = lp;
curwp->w_doto = 0;
curwp->w_flag |= WFHARD;
return(TRUE);
}
/**
* Set the mark (f == FALSE) or bookmark 'n' (f == TRUE) to the value of
* dot in the current window. No errors are possible.
*/
int SetMark(f, n)
int f, n;
{
#if BMARKS
char buf[NSTRING];
if (f == TRUE) /* set bookmark 'n' */
{
if (n >= NBMARKS) /* make sure it's in range */
n %= NBMARKS;
curwp->w_bmarkp[n] = curwp->w_dotp;
curwp->w_bmarko[n] = curwp->w_doto;
strfmt(buf, "Bookmark %d set", n);
MlWrite(buf);
}
else /* set mark */
{
#endif
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
MlWrite("Mark set");
#if BMARKS
}
#endif
return(TRUE);
}
/**
* Remove the mark and anchor (f == FALSE) or bookmark 'n' (f == TRUE) in
* the current window.
*/
int DelMark(f, n)
int f, n;
{
#if BMARKS
char buf[NSTRING];
if (f == TRUE) /* remove bookmark 'n' */
{
if (n >= NBMARKS) /* make sure it's in range */
n %= NBMARKS;
curwp->w_bmarkp[n] = NULLLPTR;
curwp->w_bmarko[n] = 0;
strfmt(buf, "Bookmark %d removed", n);
MlWrite(buf);
}
else /* remove mark and anchor */
{
#endif
curwp->w_markp = NULLLPTR;
curwp->w_marko = 0;
curwp->w_anchorp = NULLLPTR;
curwp->w_anchoro = 0;
MlWrite("Mark and anchor removed");
#if BMARKS
}
#endif
return(TRUE);
}
/**
* Unmark the current buffer's change flag
*/
int UnmarkBuf(f, n)
int f, n;
{
/* UnmarkBuf the buffer */
curbp->b_flag &= ~BFCHG;
/* UnmarkBuf all the windows into the buffer */
UpMode();
return(TRUE);
}
/**
* Swap the values of dot and mark in the current window. This is pretty
* easy, bacause all of the hard work gets done by the standard routine
* that moves the mark about. The only possible error is "no mark".
*/
int SwapMark(f, n)
int f, n;
{
LINE *odotp;
short odoto;
if (curwp->w_markp == NULLLPTR)
{
MlWrite("No mark in this window");
return(FALSE);
}
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
curwp->w_markp = odotp;
curwp->w_marko = odoto;
curwp->w_flag |= WFMOVE;
return(TRUE);
}
/**
* Set anchor to the value of dot in the current window. No errors are possible.
*/
int SetAnchor(f, n)
int f, n;
{
curwp->w_anchorp = curwp->w_dotp;
curwp->w_anchoro = curwp->w_doto;
MlWrite("Anchor set");
return(TRUE);
}
/**
* Go to a mark (f == FALSE) or bookmark 'n' (f == TRUE).
*/
int GotoMark(f, n)
int f, n;
{
#if BMARKS
char buf[NSTRING];
if (f == TRUE) /* go to bookmark 'n' */
{
if (n >= NBMARKS) /* make sure it's in range */
n %= NBMARKS;
if (curwp->w_bmarkp[n] == NULLLPTR)
{
strfmt(buf, "Bookmark %d not set in this window", n);
MlWrite(buf);
return(FALSE);
}
curwp->w_dotp = curwp->w_bmarkp[n];
curwp->w_doto = curwp->w_bmarko[n];
}
else
{
#endif
if (curwp->w_markp == NULLLPTR)
{
MlWrite("Mark not set in this window");
return(FALSE);
}
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
#if BMARKS
}
#endif
curwp->w_flag |= WFMOVE;
return(TRUE);
}
/**
* Goto the top line in the window
*/
int GotoTlow(f, n)
int f, n;
{
curgoal = GetCurCol(FALSE);
curwp->w_dotp = curwp->w_linep;
curwp->w_doto = GetGoal(curwp->w_dotp);
curwp->w_flag |= WFMOVE;
return(TRUE);
}
/**
* Goto the bottom line in the window
*/
int GotoBlow(f, n)
int f, n;
{
int tmpgoal;
tmpgoal = GetCurCol(FALSE);
curwp->w_dotp = curwp->w_linep;
ForwLine(TRUE, curwp->w_ntrows - 1);
curgoal = tmpgoal; /* ForwLine() trashes curgoal */
curwp->w_doto = GetGoal(curwp->w_dotp);
curwp->w_flag |= WFMOVE;
return(TRUE);
}