home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / edit / point20 / cursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-04  |  10.4 KB  |  462 lines

  1. #include "pt.h"
  2.  
  3. int pascal
  4. /* XTAG:cursor */
  5. cursor(fn, moveSelection)
  6.     register int fn, moveSelection;
  7. {
  8.     extern unsigned char msgBuffer[];
  9.     extern struct window *selWindow;
  10.  
  11.     int doFast, fid;
  12.  
  13. doFast = 0;
  14.  
  15. switch( fn ) {
  16.  
  17. /* These can be done by only redrawing one or two lines */
  18.  
  19. case FCURDOWN:
  20.     fid = selWindow->fileId;
  21.     /* a special case when the last line does not have a CRNL */
  22.     if( readChar(fid, fileSize(fid)-1) != '\n' )
  23.         goto wordMoves;
  24.  
  25. case FCURLEFT:
  26. case FCURRIGHT:
  27. case FCURUP:
  28.     doFast = 1;
  29.  
  30. case FWORDLEFT:
  31. case FWORDRIGHT:
  32. case FBEGINLINE:
  33. case FENDLINE:
  34. wordMoves:
  35.     fn = doCursor(fn, doFast, moveSelection);
  36.     if( fn == -1 )
  37.         goto notDefined;
  38.     break;
  39.  
  40. case FLEFTMBUTTON:
  41. case FRIGHTMBUTTON:
  42.     doMouseButtons(fn);
  43.     break;
  44.  
  45. notDefined:
  46.     msg("Key not defined", 1);
  47. default:
  48.     return 0;
  49. }
  50.  
  51. return 1;
  52. }
  53.  
  54. int pascal
  55. /* XTAG:doMouseButtons */
  56. doMouseButtons(fn)
  57.     int fn;
  58. {
  59.     extern int evhead, evtail;
  60.     extern struct event events[];
  61.     extern int mouseHorizontal, mouseVertical;
  62.     extern unsigned char msgBuffer[];
  63.  
  64.     register int i;
  65.     int j, mbStatus;
  66.  
  67.     switch( fn ) {
  68.         case FLEFTMBUTTON:
  69.             mbStatus = 0x1;
  70.             j = 0x2; /* left button pressed */
  71.             break;
  72.         case FRIGHTMBUTTON:
  73.             mbStatus = 0x2;
  74.             j = 0x8; /* right button pressed */
  75.             break;
  76.     }
  77.     /* record the button press event */
  78.     if( ++evtail >= NEVENTS )
  79.         evtail = 0;
  80.     i = evtail;
  81.     events[i].mask = j;
  82.     events[i].buttons = mbStatus;
  83.     events[i].vertical = mouseVertical;
  84.     events[i].horizontal = mouseHorizontal;
  85.     /* record the button release event */
  86.     if( ++evtail >= NEVENTS )
  87.         evtail = 0;
  88.     i = evtail;
  89.     /* event type is release button */
  90.     events[i].mask = j << 1;
  91.     events[i].buttons = 0;
  92.     events[i].vertical = mouseVertical;
  93.     events[i].horizontal = mouseHorizontal;
  94.     return 0;
  95. }
  96.  
  97. int pascal
  98. /* XTAG:doCursor */
  99. doCursor(fn, doFast, moveSelection)
  100.     int fn, doFast, moveSelection;
  101. {
  102.     extern struct window *windowList;
  103.     extern struct window *selWindow;
  104.     extern long selBegin, selEnd;
  105.     extern int mousePresent;
  106.     extern int mouseHorizontal, mouseVertical;
  107.     extern union REGS rin, rout;
  108.     extern int scrRows, scrCols;
  109.     extern int evhead, evtail;
  110.     extern unsigned char msgBuffer[];
  111.     extern int debug;
  112.     extern int cursorMouse;
  113.     extern int lastColumn;
  114.     extern int lastFn;
  115.     extern int selMode;
  116.  
  117.     long cp;
  118.     register int i, j;
  119.     unsigned char ch;
  120.     int row, col, where;
  121.     int fid, alphaNumeric;
  122.     struct window *w;
  123.  
  124.     msg("", 1);
  125.     if( mousePresent ) {
  126.         if( cursorMouse || selWindow == NULL ) {
  127.             rin.x.ax = 3;    /* get the mouse cursor position */
  128.             int86(51, &rin, &rout);
  129.             col = rout.x.cx>>3;
  130.             row = rout.x.dx>>3;
  131.         } else {
  132.             /* find the position of the current selection */
  133.             posToxy(selWindow, selBegin, &row, &col);
  134.             /* special case so that cursor up and down move */
  135.             /* down the page in a straight line so far as is */
  136.             /* possible */
  137.             if( (lastColumn != -1) && (col != lastColumn)
  138.              && (lastFn==FCURUP || lastFn==FCURDOWN)
  139.             )
  140.                 col = lastColumn;
  141.         }
  142.     } else {    /* find the current mouse cursor position */
  143.         getCPos(&row, &col);
  144.     }
  145.     /* convert to screen pixels */
  146.     i = col << 3;
  147.     j = row << 3;
  148.  
  149.     /* adjust it according to the function invoked */
  150.     switch( fn ) {
  151.  
  152.     case FWORDLEFT:
  153.     doWordLeft:
  154.         xyToPos(&row, &col, &where, &cp, &w);
  155.         if( where != INSIDEWINDOW )
  156.             break;
  157.  
  158.         fid = w->fileId;
  159.  
  160.         /* skip the white space between words */
  161.         while( cp >= 0 ) {
  162.             ch = readChar(fid, --cp);
  163.             if( !isspace(ch))
  164.                 break;
  165.         }
  166.  
  167.         alphaNumeric = isalnum(ch);
  168.         /* skip the characters in the word */
  169.         while( 1 ) {
  170.             ch = readChar(fid, --cp);
  171.                 /****** OLD VERSION.  vi "big" words *******/
  172.                 /*if(ch==' '||ch=='\t'||ch=='\n'||ch=='\0')*/
  173.                 /*******************************************/
  174.             /* if we have switched from alphanumeric to not */
  175.             /* alphanumeric or the reverse, then quit */
  176.             if( alphaNumeric ) {
  177.                 if( !isalnum(ch) && ch != '_' ) {
  178.                     ++cp;
  179.                     break;
  180.                 }
  181.             } else if( isalnum(ch) || isspace(ch) || ch=='_' ) {
  182.                 ++cp;
  183.                 break;
  184.             }
  185.         }
  186.  
  187.     finishUp:
  188.         posToxy(w, cp, &row, &col);
  189.         if( moveSelection ) {
  190.             selBegin = selEnd = cp;
  191.             if( indentToShowSelection(-1) ) {
  192.                 redrawBox(selWindow->row1, selWindow->col1,
  193.                     selWindow->row2, selWindow->col2);
  194.                 updateScreen(selWindow->row1,
  195.                     selWindow->row2);
  196.                 posToxy(w, cp, &row, &col);
  197.             }
  198.         }
  199.         i = col << 3;
  200.         j = row << 3;
  201.         break;
  202.  
  203.     case FWORDRIGHT:
  204.     doWordRight:
  205.  
  206.         xyToPos(&row, &col, &where, &cp, &w);
  207.         if( where != INSIDEWINDOW )
  208.             break;
  209.  
  210.         fid = w->fileId;
  211.  
  212.         ch = readChar(fid, cp);
  213.         alphaNumeric = isalnum(ch);
  214.  
  215.         /* skip the characters in the word */
  216.         while( 1 ) {
  217.             ch = readChar(fid, ++cp);
  218.                 /****** OLD VERSION.  vi "big" words *******/
  219.                 /***if( ch==' ' || ch=='\n' || ch=='\0' )***/
  220.                 /*******************************************/
  221.             /* if we have switched from alphanumeric to not */
  222.             /* alphanumeric or the reverse, then quit */
  223.             if( alphaNumeric ) {
  224.                 if( !isalnum(ch) && ch != '_' )
  225.                     break;
  226.             } else if( isalnum(ch) || isspace(ch) || ch=='_' )
  227.                 break;
  228.         }
  229.  
  230.         /* skip the white space between words */
  231.         while( isspace(ch) )
  232.             ch = readChar(fid, ++cp);
  233.  
  234.         goto finishUp;
  235.  
  236.     case FENDLINE:
  237.         xyToPos(&row, &col, &where, &cp, &w);
  238.         if( where != INSIDEWINDOW )
  239.             break;
  240.         fid = w->fileId;
  241.         while( 1 ) {
  242.             ch = readChar(fid, cp++);
  243.             if( ch == '\n' || ch == '\0' )
  244.                 break;
  245.         }
  246.         --cp;        /* we went one past the NL */
  247.         goto finishUp;
  248.  
  249.     case FBEGINLINE:
  250.         xyToPos(&row, &col, &where, &cp, &w);
  251.         if( where != INSIDEWINDOW )
  252.             break;
  253.         fid = w->fileId;
  254.         if( readChar(fid, cp) == '\n' )
  255.             --cp;
  256.         while( cp >= -2 ) {
  257.             ch = readChar(fid, cp--);
  258.             if( ch == '\n' )
  259.                 break;
  260.         }
  261.         ++cp;    /* cp now points to the '\n' */
  262.         /* skip tabs and blanks */
  263.         while( 1 ) {
  264.             ch = readChar(fid, ++cp);
  265.             if( ch != ' ' && ch != '\t' )
  266.                 break;
  267.         }
  268.         goto finishUp;
  269.  
  270.     case FCURRIGHT:
  271.         switch( selMode ) {
  272.             default:
  273.             case SELCHAR:
  274.                 break;
  275.             case SELWORD:
  276.                 goto doWordRight;
  277.             case SELLINE:
  278.                 goto doCurDown;
  279.         }
  280.         if( i < (8*(scrCols-1)) )
  281.             i += 8;
  282.         break;
  283.  
  284.     case FCURLEFT:
  285.         switch( selMode ) {
  286.             default:
  287.             case SELCHAR:
  288.                 break;
  289.             case SELWORD:
  290.                 goto doWordLeft;
  291.             case SELLINE:
  292.                 goto doCurUp;
  293.         }
  294.         if( i > 0 )
  295.             i -= 8;
  296.         break;
  297.  
  298.     case FCURUP:
  299.     doCurUp:
  300.         if( j > 0 )
  301.             j -= 8;
  302.         break;
  303.  
  304.     case FCURDOWN:
  305.     doCurDown:
  306.         if( j < (8*(scrRows-1)) )
  307.             j += 8;
  308.         break;
  309.  
  310.     default:
  311.         return -1;
  312.     }
  313.  
  314.     mouseHorizontal = i;
  315.     mouseVertical = j;
  316.  
  317.     doScreenUpdate(fn, i, j, doFast, moveSelection);
  318.     return 0;
  319. }
  320.  
  321.  
  322. void pascal
  323. /* XTAG:doScreenUpdate */
  324. doScreenUpdate(fn, i, j, doFast, moveSelection)
  325.     int fn, i, j, doFast, moveSelection;
  326. {
  327.     extern struct window *selWindow;
  328.     extern struct window *windowList;
  329.     extern long selBegin, selEnd;
  330.     extern int selMode;
  331.     extern union REGS rin, rout;
  332.     extern int mouseHorizontal, mouseVertical;
  333.     extern int scrRows, scrCols;
  334.     extern int evhead, evtail;
  335.     extern struct event events[];
  336.     extern unsigned char msgBuffer[];
  337.     extern int debug;
  338.     extern int cursorMouse;
  339.     extern int lastColumn;
  340.  
  341.     long cp, oldSelBegin;
  342.     unsigned char ch;
  343.     int n, row, col, row2, where;
  344.     register struct window *w;
  345.     struct window *w2;
  346.  
  347.     row = j >> 3;
  348.     col = i >> 3;
  349.     lastColumn = col;
  350.     rin.x.ax = 2;    /* hide cursor */
  351.     int86(51, &rin, &rout);
  352.     rin.x.ax = 4;    /* move cursor */
  353.     rin.x.cx = i;
  354.     rin.x.dx = j;
  355.     int86(51, &rin, &rout);
  356.     rin.x.ax = 1;    /* show cursor */
  357.     int86(51, &rin, &rout);
  358.     if( moveSelection && !cursorMouse ) {
  359.  
  360.         xyToPos(&row, &col, &where, &cp, &w2);
  361.         w = w2;
  362.  
  363.         /* This is to prevent the right cursor movement from */
  364.         /* getting stuck on a tab.  It should happen only when */
  365.         /* the selection is on a tab. */
  366.         if( selBegin == cp && selEnd == cp && fn == FCURRIGHT )
  367.             ++cp;
  368.  
  369.         /* see if we scrolled off an edge of the window */
  370.         if( where != INSIDEWINDOW && selWindow != NULL) {
  371.             w = selWindow;
  372.             if( row > (w->row2-1) ) {
  373.                 n = (w->row2-w->row1+1)/3;
  374.                 w->posTopline = nextLine(w->fileId,
  375.                             w->posTopline, &n);
  376.                 w->numTopline += n;
  377.                 row -= n;
  378.             } else if( row < (w->row1+1) ) {
  379.                 n = (w->row2-w->row1+1)/3;
  380.                 w->posTopline = prevLine(w->fileId,
  381.                             w->posTopline, &n);
  382.                 w->numTopline -= n;
  383.                 row += n;
  384.             }
  385.             redrawBox(w->row1, w->col1, w->row2, w->col2);
  386.             updateScreen(w->row1, w->row2);
  387.             xyToPos(&row, &col, &where, &cp, &w2);
  388.             w = w2;
  389.             doFast = 0;
  390.         }
  391.  
  392.         if( where == INSIDEWINDOW ) {
  393.             /* if the cursor is off the screen then disable     */
  394.             /* the fast cursor motion since it screws up the */
  395.             /* display we set doFast=0 to disable the fast     */
  396.             /* cursor motion.  Also, do not do fast if the   */
  397.             /* selection mode is not character         */
  398.             if( selBegin < w->posTopline
  399.              || selEnd >= w->posBotline
  400.              || selMode != SELCHAR
  401.             )
  402.                 doFast = 0;
  403.             
  404.             /* this speeds up simple cursor movements */
  405.              if( selBegin == selEnd && doFast ) {
  406.                  oldSelBegin = selBegin;
  407.                 selEnd = selBegin = cp;
  408.                 ch = readChar(w->fileId, selBegin);
  409.                 /* do not allow a NL to be selected */
  410.                 /* without a CR */
  411.                 if( ch == '\n' )
  412.                     selBegin--;
  413.                 n = -1;
  414.                 if( (cp < oldSelBegin-1)
  415.                  || (cp == oldSelBegin-1 && ch == '\n') ) {
  416.                     row2 = row + 1;
  417.                     oldSelBegin = prevLine(w->fileId, cp,
  418.                         &n);
  419.                 } else {
  420.                     if( cp > oldSelBegin+2
  421.                      || (cp == oldSelBegin+2
  422.                      && ch != '\n') )
  423.                         row2 = row--;
  424.                     else
  425.                         row2 = row;
  426.                     oldSelBegin = prevLine(w->fileId,
  427.                         oldSelBegin,&n);
  428.                 }
  429.                 setMap(row, 0, row2, scrCols-1, 1, 0x07);
  430.                 maskTop(selWindow);
  431.                 oldSelBegin = fillLine(w, oldSelBegin,
  432.                     row, w->col1+1, w->col2-1);
  433.                 if( row != row2 )
  434.                     fillLine(w, oldSelBegin,
  435.                         row2, w->col1+1, w->col2-1);
  436.                 updateScreen(row, row2);
  437.             } else {
  438.                  n = selMode;
  439.                 select(w, cp, row, col, -1);
  440.                 selMode = n;
  441.                 modeExtend(w, selBegin, &selBegin, &selEnd);
  442.                 setMap(row, 0, row, scrCols-1, 1, 0x07);
  443.                 maskTop(selWindow);
  444.                 n = -1;
  445.                 oldSelBegin=prevLine(w->fileId, selBegin, &n);
  446.                 fillLine(w, oldSelBegin, row, w->col1+1,
  447.                     w->col2-1);
  448.                 updateScreen(row, row);
  449.             }
  450.         }
  451.     } else {
  452.         setCPos(row, col);
  453.     }
  454.     if( ++evtail >= NEVENTS )
  455.         evtail = 0;
  456.     i = evtail;
  457.     events[i].mask = 0x1;
  458.     events[i].buttons = 0;
  459.     events[i].vertical = mouseVertical;
  460.     events[i].horizontal = mouseHorizontal;
  461. }
  462.