home *** CD-ROM | disk | FTP | other *** search
- #include "pt.h"
- #include "conio.h"
-
- /* return 1 only if you see both buttons simultaneously down */
- int pascal
- /* XTAG:followSelection */
- followSelection(w, lastRow, lastCol, evHead, oneTime)
- struct window *w;
- int lastRow, lastCol, evHead, oneTime;
- {
- extern unsigned char msgBuffer[];
- extern long selBegin, selEnd;
- extern int selMode;
- extern union REGS rin, rout;
- extern int scrRows, scrCols;
- extern struct event events[];
- extern unsigned char scrMapReset;
- extern int mousePresent;
- extern int autoScrollRate;
- extern int debug;
- extern int videoMode;
-
- int col1, col2, l, m, n, r, fileId, ret;
- int oldRow1, oldRow2, newRow1, newRow2;
- int selRow1, selRow2, redoRow1, redoRow2;
- int anchRow1, anchRow2, curRow, curCol;
- int startButtons;
- long cpNew, cpNew1, cpNew2, cp1;
- long anchBegin, anchEnd, oldCp1, anchCp1;
- long selCp1;
-
- /* get the present mouse button state */
- if( mousePresent ) {
- rin.x.ax = 3;
- int86(51, &rin, &rout);
- startButtons = rout.x.bx;
- } else
- startButtons = 0x7;
-
- /* anchor the selection at the current selection */
- anchBegin = selBegin;
- anchEnd = selEnd;
- fileId = w->fileId;
- col1 = w->col1 + 1;
- col2 = w->col2 - 1;
- ret = 0;
-
- restartFollowing:
- /* what rows is the selection on now? */
- if( selBegin <= w->posTopline ) {
- anchCp1 = w->posTopline;
- anchRow1 = w->row1 + 1;
- } else {
- n = -1;
- anchCp1 = prevLine(fileId, selBegin, &n);
- posToxy(w, selBegin, &anchRow1, &r);
- }
- oldRow1 = anchRow1;
- oldCp1 = anchCp1;
-
- posToxy(w, selEnd, &anchRow2, &r);
- oldRow2 = anchRow2;
- if( oneTime ) {
- curRow = lastRow;
- curCol = lastCol;
- goto firstTime;
- }
-
- /* This is the loop that follows the cursor selection */
- while( 1 ) {
- /* first find out the current cursor position and */
- /* see if it has moved since we last checked */
- /* wait for a mouse event */
- while( !isMouseEvent(0) ) {
- /* This is a BIOS call that does not have any */
- /* direct purpose. It seems to be necessary so */
- /* that things will not freeze up after a Ctrl-C */
- /* is handled. I'm not sure why. */
- getCPos(&l, &m);
- }
- evHead = getMouseEvent();
- /* skip intermediate mouse movements if other mouse events */
- /* are already on the queue */
- while( 1 ) {
- if( events[evHead].mask != 0x1 )
- break;
- if( !isMouseEvent(0) )
- break;
- evHead = getMouseEvent();
- }
- curRow = events[evHead].vertical>>3;
- curCol = events[evHead].horizontal>>3;
-
- /* normalize extension outside the window */
- if( curRow <= w->row1 ) {
- curRow = w->row1 + 1;
- while( 1 ) {
- /* set up the screen map and scroll window */
- scrMapReset = 0;
- setMap(w->row1, w->col1, w->row2, w->col2,
- 1, w->textColor);
- maskTop(w);
- downScroll(w, autoScrollRate);
- /* change the selection */
- l = w->row1 + 1;
- m = w->col1 + 1;
- xyToPos(&l, &m, &n, &cp1,
- (struct window **)&r);
- if( selBegin > cp1 )
- selBegin = cp1;
- redrawBox(0, 0, scrRows-1, scrCols-1);
- scrMapReset = 1;
- setMap(w->row1, w->col1, w->row2, w->col2,
- 1, w->textColor);
- oldRow1 = w->row1 + 1;
- oldCp1 = w->posTopline;
- oldRow2 = w->row2 - 1;
- if( isMouseEvent(0) ) {
- evHead = getMouseEvent();
- goto restartFollowing;
- }
- }
- } else if( curRow >= w->row2 ) {
- curRow = w->row2 - 1;
- while( 1 ) {
- /* set up the screen map and scroll window */
- scrMapReset = 0;
- setMap(w->row1, w->col1, w->row2, w->col2,
- 1, w->textColor);
- maskTop(w);
- upScroll(w, autoScrollRate);
- /* change the selection */
- l = w->row2 - 1;
- m = w->col2 - 1;
- xyToPos(&l, &m, &n, &cp1,
- (struct window **)&r);
- if( selEnd < cp1 )
- selEnd = cp1;
- redrawBox(0, 0, scrRows-1, scrCols-1);
- scrMapReset = 1;
- setMap(w->row1, w->col1, w->row2, w->col2,
- 1, w->textColor);
- oldRow1 = w->row1 + 1;
- oldCp1 = w->posTopline;
- oldRow2 = w->row2 - 1;
- if( isMouseEvent(0) ) {
- evHead = getMouseEvent();
- goto restartFollowing;
- }
- }
- } else if( curCol <= w->col1 ) {
- curCol = w->col1 + 1;
- } else if( curCol >= w->col2 ) {
- curCol = w->col2 - 1;
- }
-
- if( curRow != lastRow || curCol != lastCol ) {
- firstTime:
- /* The cursor has moved, so update the selection */
- /* get the file position of the cursor position */
- cpNew = xyToWindow(w, &curRow, &curCol);
-
- /* Extend it according the the selection mode */
- modeExtend(w, cpNew, &cpNew1, &cpNew2);
-
- if( cpNew1 < anchBegin ) {
- selBegin = cpNew1;
- newRow1 = curRow;
- n = -1;
- cp1 = prevLine(fileId, cpNew1, &n);
- } else {
- selBegin = anchBegin;
- newRow1 = anchRow1;
- cp1 = anchCp1;
- }
- if( cpNew2 > anchEnd ) {
- selEnd = cpNew2;
- newRow2 = curRow;
- } else {
- selEnd = anchEnd;
- newRow2 = anchRow2;
- }
-
- /* remember the rows of the current selection */
- selRow1 = newRow1;
- selCp1 = cp1;
- selRow2 = newRow2;
-
- /* what rows do we need to redraw? */
- /* we need to erase the old selection as well as */
- /* draw the new selection */
- if( oldRow1 < newRow1 ) {
- newRow1 = oldRow1;
- cp1 = oldCp1;
- } else
- oldCp1 = cp1;
- if( oldRow2 > newRow2 )
- newRow2 = oldRow2;
-
- /* try to reduce the screen redrawing by figuring */
- /* out which rows have actually changed */
- /* do not optimize for movement above the anchor row */
- if( selRow1 == oldRow1 && selRow1 >= anchRow1) {
- if( selRow2 >= oldRow2 ) {
- redoRow1 = oldRow2;
- redoRow2 = selRow2;
- } else {
- redoRow1 = selRow2;
- redoRow2 = oldRow2;
- }
- } else {
- redoRow1 = newRow1;
- redoRow2 = newRow2;
- }
-
- /* update the changed rows in the screen buffer */
- for(r = newRow1; r <= redoRow2; r++) {
- if( redoRow1 <= r ) {
- cp1 = fillLine(w, cp1, r, col1, col2);
- } else {
- n = 1;
- cp1 = nextLine(fileId, cp1, &n);
- }
- if( cp1 == -1 ) /* EOF? */
- break;
- }
- if( oneTime ) {
- oneTime = 0;
- updateScreen(0, scrRows-1);
- } else {
- updateScreen(redoRow1, redoRow2);
- }
-
- /* remember some things for the next iteration */
- oldRow1 = selRow1;
- oldCp1 = selCp1;
- oldRow2 = selRow2;
- lastRow = curRow;
- lastCol = curCol;
- }
-
- /* are the buttons up now? */
- if( events[evHead].buttons == 0 )
- break;
-
- /* check for both buttons down */
- if( ((~startButtons) & events[evHead].buttons) != 0 ) {
- ret = 1;
- break;
- }
- }
-
- /* selecting the end of line should include both CR and LF */
- if( readChar(fileId, selBegin) == '\n' ) {
- if( readChar(fileId, --selBegin) != '\r' )
- ++selBegin;
- }
- return ret;
- }
-