home *** CD-ROM | disk | FTP | other *** search
- #include "pt.h"
-
- void pascal
- /* XTAG:xyToPos */
- xyToPos(inRow, inCol, where, pos, wOut)
- int *inRow, *inCol;
- register int *where;
- long *pos;
- struct window **wOut;
- {
- extern unsigned char msgBuffer[];
- extern struct window *windowList;
- extern int tabWidth;
- extern int debug;
- extern int menuLine;
- extern int scrRows, scrCols;
-
- register struct window *w;
- long cp, cp2;
- int n, tabStop, rowsDown, iBuffer, iLine;
- int row, col;
- int doRowCache, eofFlag;
- unsigned char ch, nullChar;
- unsigned char far *firstByte;
- unsigned char far *lastByte;
-
- eofFlag = 0;
- row = *inRow;
- if( (menuLine > 0 && row == 0)
- || (menuLine < 0 && row == (scrRows-1)) ) {
- *where = TOPLINE;
- *wOut = NULL;
- return;
- }
- col = *inCol;
- w = windowList;
- do {
- /* see if this screen coordinate is in this window */
-
- /* above this window? */
- if( row < w->row1 )
- continue;
-
- /* below this window? */
- if( row > w->row2 )
- continue;
-
- /* left of this window? */
- if( col < w->col1 )
- continue;
-
- /* right of this window? */
- if( col > w->col2 )
- continue;
-
- /* it is this window so return its address */
- *wOut = w;
-
- /* on the upper border? */
- if( row == w->row1 ) {
- if( col == w->col1 )
- *where = UPPERLEFT;
- else if( w->col2 == col )
- *where = UPPERRIGHT;
- else
- *where = UPPERBORDER;
- }
- /* one the lower border? */
- else if( row == w->row2 ) {
- if( col == w->col1 )
- *where = LOWERLEFT;
- else if( col == w->col2 )
- *where = LOWERRIGHT;
- else
- *where = LOWERBORDER;
- }
- /* on the left border? */
- else if( col == w->col1 )
- *where = LEFTBORDER;
- /* on the right border? */
- else if( col == w->col2 )
- *where = RIGHTBORDER;
- /* else it must be inside */
- else {
- *where = INSIDEWINDOW;
- rowsDown = row - w->row1 - 1; /* rows down */
- /* has window moved since we last found a line? */
- doRowCache = 1;
- if( w->lastPosTop == w->posTopline ) {
- /* if so find the new line relative to it */
- cp = w->posCurLast;
- rowsDown -= w->rowCurLast;
- if( rowsDown < 0 ) {
- rowsDown = -rowsDown;
- cp=prevLine(w->fileId,cp,&rowsDown);
- } else if( rowsDown > 0 )
- goto countDown;
- } else {
- /* just count down from the top line */
- cp = w->posTopline;
- countDown:
- n = rowsDown;
- cp = nextLine(w->fileId, cp, &rowsDown);
- /* fix so that EOF works */
- if( (n -= rowsDown) > 0 ) {
- *inRow -= n;
- doRowCache = 0;
- }
- /* see if EOF on a line alone */
- if( (cp-1) > 0 &&
- readChar(w->fileId,cp-1)!='\n') {
- /* another fix so EOF works */
- --*inRow;
- doRowCache = 0;
- }
- }
- /* if we are near end of file, "row" and the */
- /* "cp" will not really be right. The +3 is */
- /* superstitious but I want to be sure we don't get */
- /* get off on the counts. There is little need */
- /* to optimize at the end of the file, we can forgo */
- /* that to be safe */
- if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
- /* compute the number of rows down */
- w->rowCurLast = row - w->row1 - 1;
- w->posCurLast = cp;
- w->lastPosTop = w->posTopline;
- } else
- w->lastPosTop = -1;
- n = col - w->col1 - 1 + w->indent;
- iBuffer = 0;
- iLine = 0;
- firstByte = (unsigned char far *)1;
- lastByte = (unsigned char far *)0;
- cp2 = cp;
- while( iLine <= n ) {
- if( firstByte > lastByte ) {
- if(getSpan(w->fileId, cp2, &firstByte,
- &lastByte, 0) ) {
- nullChar = 0;
- eofFlag = 1;
- firstByte = &nullChar;
- lastByte = firstByte;
- }
- }
- ++cp2;
- ++iBuffer;
- ch = *firstByte++;
- switch( ch ) {
- case '\n': /* end of line */
- goto endLoop;
- case 0: /* end of file */
- if( eofFlag )
- goto endLoop;
- else
- goto justACharacter;
- case '\t':
- tabStop = iLine + tabWidth
- - (iLine % tabWidth);
- if( tabStop > n )
- goto endLoop;
- else
- iLine = tabStop;
- break;
- case '\r': /* ignore CRs */
- /* unless they are not followed */
- /* by a NL */
- if( *firstByte == '\n' )
- break;
- /* else drop through */
- default:
- justACharacter:
- iLine++;
- break;
- }
- }
- endLoop:
- *pos = cp + iBuffer - 1;
- }
- return;
- } while( (w = w->nextWindow) != NULL );
-
- *where = OUTSIDEWINDOW;
- *wOut = NULL;
- }
-
- long pascal
- /* XTAG:xyToWindow */
- xyToWindow(w, inRow, inCol)
- register struct window *w;
- int *inRow, *inCol;
- {
- extern unsigned char msgBuffer[];
- extern unsigned char textBuffer[];
- extern struct window *windowList;
- extern int tabWidth;
- extern int debug;
-
- long cp, cp2;
- int n, tabStop, rowsDown, iBuffer, iLine;
- int row, col;
- int doRowCache, eofFlag;
- unsigned char ch, nullChar;
- unsigned char far *firstByte;
- unsigned char far *lastByte;
-
- eofFlag = 0;
- row = *inRow;
- col = *inCol;
- /* handle the cases where the cursor is outside of the window */
- /* return the nearest character in the window */
- /* if above or below, use the nearest line */
- if( row <= w->row1 )
- row = w->row1 + 1;
- else if( row >= w->row2 )
- row = w->row2 - 1;
- /* if to the side, use the nearest column */
- if( col <= w->col1 )
- col = w->col1 + 1;
- else if( col >= w->col2 )
- col = w->col2 - 1;
-
- /* now find the character position in the file */
- rowsDown = row - w->row1 - 1;
- /* rows down from the top line displayed in the window */
- doRowCache = 1;
- /* Has the window text moved since we last found a line? */
- if( w->lastPosTop == w->posTopline ) {
- /* if so find the new line relative to it */
- cp = w->posCurLast;
- rowsDown -= w->rowCurLast;
- /* adjust rows down by where the cached line is */
- if( rowsDown < 0 ) {
- /* line to find is above the cached line */
- rowsDown = -rowsDown;
- cp = prevLine(w->fileId, cp, &rowsDown);
- } else if( rowsDown > 0 )
- /* line to find is below the cached line */
- goto countDown;
- /* count down the lines from the cached line */
- } else {
- /* if not, just count down from the top line */
- cp = w->posTopline;
- countDown:
- n = rowsDown; /* remember how many we asked to count down */
- cp = nextLine(w->fileId, cp,
- &rowsDown);
- /* fix so that EOF works */
- /* rowsDown is how many nextLine actually went down */
- /* if n > rowsDown then we hit EOF */
- if( (n -= rowsDown) > 0 ) {
- /* tell the caller the hit was below the last line */
- *inRow -= n;
- doRowCache = 0;
- }
- /* see if the EOF marker NOT is on a line alone */
- /* this will be try if nextLine stopped at the EOF marker */
- /* and the last real character is NOT a newline */
- /* The first test is a fix when you are at the beginning */
- /* of the file */
- if( cp != 0L && readChar(w->fileId, cp-1) != '\n' ) {
- /* another fix so that EOF works */
- --*inRow;
- doRowCache = 0;
- }
- }
- /* if we are near the end of file the "row" and the "cp" */
- /* will not really be right. The +3 is superstitious but */
- /* I want to be sure we don't get off on the counts. There */
- /* is little need to optimize at the end of the file, we */
- /* can forgo that to be safe */
- if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
- w->rowCurLast = row - w->row1 - 1; /* rows down */
- w->posCurLast = cp;
- w->lastPosTop = w->posTopline;
- } else
- w->lastPosTop = -1;
-
- /* figure out the physical column */
- n = col - w->col1 - 1 + w->indent;
-
- /* now we have to figure out the text file position by */
- /* reconstructing the line */
- iBuffer = 0;
- iLine = 0;
- firstByte = (unsigned char far *)1;
- lastByte = (unsigned char far *)0;
- cp2 = cp;
- while( iLine <= n ) {
- if( firstByte > lastByte ) {
- if(getSpan(w->fileId, cp2, &firstByte, &lastByte,0)){
- nullChar = 0;
- eofFlag = 1;
- firstByte = &nullChar;
- lastByte = firstByte;
- }
- }
- ++cp2;
- ++iBuffer;
- ch = *firstByte++;
- switch( ch ) {
- case '\n': /* end of line */
- goto endLoop;
- case 0: /* end of file */
- if( eofFlag )
- goto endLoop;
- else
- goto justACharacter;
- case '\t':
- tabStop = iLine + tabWidth - (iLine % tabWidth);
- if( tabStop > n )
- goto endLoop;
- else
- iLine = tabStop;
- break;
- case '\r': /* ignore CRs */
- /* unless they are not followed by a NL */
- if( *firstByte == '\n' )
- break;
- /* else drop through */
- default:
- justACharacter:
- iLine++;
- break;
- }
- }
- endLoop:
- return cp + iBuffer - 1;
- }
-
- long pascal
- /* XTAG:posToxy */
- posToxy(w, pos, outRow, outCol)
- register struct window *w;
- long pos;
- int *outRow, *outCol;
- {
- extern unsigned char msgBuffer[];
- extern unsigned char textBuffer[];
- extern struct window *windowList;
- extern int tabWidth;
-
- long cp, cp2, fSize;
- int n, tabStop, row, lastRow, iLine;
- unsigned char ch;
-
- /* handle the case where the position is above the window */
- /* return the nearest character in the window */
- if( pos < w->posTopline ) {
- *outRow = w->row1 + 1;
- *outCol = w->col1 + 1;
- return w->posTopline;
- }
-
- /* find out which row it is on */
- fSize = fileSize(w->fileId);
- cp = w->posTopline;
- row = w->row1 + 1;
- lastRow = w->row2 - 1;
- while( row < lastRow ) {
- n = 1;
- cp2 = nextLine(w->fileId, cp, &n);
- if( pos < cp2 )
- break;
- else if( cp2 == fSize ) {
- if( readChar(w->fileId, cp2-1) == '\n' ) {
- cp = cp2;
- ++row;
- }
- break;
- }
- cp = cp2;
- ++row;
- }
- *outRow = row;
- cp2 = cp; /* save for the return */
-
- /* now we have to figure out the column by */
- /* reconstructing the line */
- iLine = 0;
- /* count out the line the way "fillLine" would */
- while( cp < pos ) {
- ch = readChar(w->fileId, cp++);
- switch( ch ) {
- case 0: /* end of file */
- case '\n': /* end of line */
- goto endLoop;
- case '\t':
- tabStop = iLine + tabWidth - (iLine % tabWidth);
- iLine = tabStop;
- break;
- case '\r': /* ignore CRs if they are followed by a NL */
- if( readChar(w->fileId, cp) == '\n' )
- break;
- /* else drop through */
- default:
- iLine++;
- break;
- }
- }
- endLoop:
- *outCol = w->col1 + 1 + iLine - w->indent;
- return cp2;
- }
-