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

  1. #include "pt.h"
  2. #include "string.h"
  3.  
  4. /* XTAG:maxLineLength */
  5. static int maxLineLength = 1;
  6.  
  7. void pascal
  8. /* XTAG:drawWindow */
  9. drawWindow(w)
  10.     register struct window *w;
  11. {
  12.     extern unsigned char border1[], border2[], border3[], border4[];
  13.     extern struct window *activeWindow;
  14.     extern int debug;
  15.     
  16.     register unsigned char *border;
  17.  
  18.     fillWindow(w, 1);
  19.     /* put in the banner first so the box will not overwrite it */
  20.     banner(w);
  21.     if( w != activeWindow )
  22.         border = &border1[0];
  23.     else
  24.         border = &border2[0];
  25.     drawBorder(border, w->row1, w->col1, w->row2, w->col2,
  26.         w->borderColor, 0);
  27.     updateScreen(w->row1, w->row2);
  28. }
  29.  
  30. void pascal
  31. /* XTAG:drawBorder */
  32. drawBorder(border, row1, col1, row2, col2, borderColor, bottomLineOnly)
  33.     unsigned char *border;
  34.     int row1, row2, col1, col2, borderColor, bottomLineOnly;
  35. {
  36.     register int i;
  37.     
  38.     if( !bottomLineOnly ) {
  39.         /* put in the top two corners */
  40.         displayChar(row1, col1, 254, borderColor);
  41.         displayChar(row1, col2, 254, borderColor);
  42.  
  43.         /* put in the top border of the box */
  44.         displayChar(row1, col1, border[0], borderColor);
  45.         for(i = col1+1; i < col2; i++)
  46.         displayChar(row1, i, border[1], borderColor);
  47.         displayChar(row1, col2, border[2], borderColor);
  48.  
  49.         /* put in the sides of the box */
  50.         for(i = row1+1; i < row2; i++) {
  51.             displayChar(i, col1, border[3], borderColor);
  52.             displayChar(i, col2, border[4], borderColor);
  53.         }
  54.     }
  55.  
  56.     /* put in the bottom two corners */
  57.     displayChar(row2, col1, 254, borderColor);
  58.     displayChar(row2, col2, 254, borderColor);
  59.     /* put in the bottom row of the box */
  60.     displayChar(row2, col1, border[5], borderColor);
  61.     for(i = col1+1; i < col2; i++)
  62.         displayChar(row2, i, border[6], borderColor);
  63.     displayChar(row2, col2, border[7], borderColor);
  64. }
  65.  
  66. void pascal
  67. /* XTAG:banner */
  68. banner(w)
  69.     register struct window *w;
  70. {
  71.     extern unsigned char border1[8];
  72.     extern unsigned char textBuffer[];
  73.     extern int overType;
  74.     extern struct openFile *files;
  75.     extern int pathNames;
  76.     extern struct window *activeWindow;
  77.     extern unsigned int piecesLeft;
  78.     extern unsigned int bytesLeft;
  79.     extern int debug;
  80.  
  81.     register int i;
  82.     int row1, row2, col, len;
  83.     int stopBlink, color;
  84.     unsigned char fillChar;
  85.     long lp;
  86.     struct openFile *ff;
  87.  
  88.     /* see if we need a scroll bar on the bottom border */
  89.     len = w->col2 - w->col1 - 1;
  90.     if( len < maxLineLength || w->indent > 0 ) {
  91.         /* fill in the highlighted, bottom side position bar */
  92.         /* we are reusing the row1, row2 variables */
  93.         /* they really represent columns here */
  94.         row1 = 1 + (w->col1) + (len*w->indent) / maxLineLength;
  95.         row2 = 1 + (w->col1) + (len*(len+w->indent)) / maxLineLength;
  96.         if( row2 >= w->col2 )
  97.             row2 = w->col2 - 1;
  98.         if( row1 > row2 )
  99.             row1 = row2;
  100.         for(i = row1; i <= row2; i++)
  101.             displayChar(w->row2, i, 196, w->elevColor);
  102.     }
  103.  
  104.     /* does this window have a banner at all? */
  105.     if( (w->state & 0x8) == 0x8 )
  106.         return;
  107.     if( w != activeWindow )
  108.         fillChar = ' ';
  109.     else
  110.         fillChar = 205;
  111.     if( w->fileId == -1 ) {
  112.         lp = 0;
  113.         w->numTopline = 0;
  114.         w->numBotline = 1;
  115.     } else {
  116.         ff = &files[w->fileId];
  117.         lp = ff->fileSize;
  118.     }
  119.     i = 0;
  120.     if(  w->numTopline >= w->numBotline )
  121.         i = 1;
  122.     col = (pathNames ? 0 : w->nameOffset);
  123.     stopBlink = ((bytesLeft < SPACELOW)  && (piecesLeft == 0) ? 5 : 0);
  124.     sprintf(textBuffer,
  125.         "%c%s \256%s\257%s%s%s%s  lines %d-%d  columns %d-%d",
  126.         fillChar,
  127.         (stopBlink == 5 ? "SAVE" : ""),
  128.         &((files[w->fileId].origName)[col]),
  129.         /* three state flags */
  130.         (files[w->fileId].isChanged ? "*" : ""),
  131.         (overType ? "  OverType" : ""),
  132.         (ff->readOnly ? "  ReadOnly" : ""),
  133.         ( ( (w->state & 0x2) == 0x2) ? "  UNIX" : ""),
  134.         /* line and column numbers */
  135.         w->numTopline - i, w->numBotline - 1,
  136.         w->indent + 1, (w->col2 - w->col1 + w->indent - 1));
  137.     len = strlen(textBuffer);
  138.     row1 = w->row1;
  139.     col = w->col1 + 1;
  140.     for(i = 0; textBuffer[i] != '\0'; i++) {
  141.         if( i < stopBlink && i > 0 )
  142.             color = 0xF8;
  143.         else
  144.             color = w->bannerColor;
  145.         displayChar(row1, col++, textBuffer[i], color);
  146.         if( col >= w->col2 )
  147.             break;
  148.     }
  149.     /* fill top row with reverse video spaces */
  150.     while( col < w->col2 )
  151.         displayChar(row1, col++, fillChar, w->bannerColor);
  152.  
  153.     /* fill in the highlighted, left side position bar */
  154.     row1 = 1 + (w->row1) +
  155.         (int)(((long)(w->row2-w->row1-1) * w->posTopline) / (lp+1L));
  156.     row2 = 1 + (w->row1) +
  157.         (int)(((long)(w->row2-w->row1-1) * w->posBotline) / (lp+1L));
  158.     for(i = row1; i <= row2; i++) {
  159.         displayChar(i, w->col1, 179, w->elevColor);
  160.     }
  161. }
  162.  
  163. void pascal
  164. /* XTAG:fillWindow */
  165. fillWindow(w, doUpdates)
  166.     register struct window *w;
  167. {
  168.     extern unsigned char *screenMap;
  169.     extern unsigned char *screenChars;
  170.     extern unsigned char scrMapReset;
  171.     extern unsigned int dispMemory;
  172.     extern int debug;
  173.     extern int scrRows, scrCols;
  174.  
  175.     long cp;
  176.     int n;
  177.     int row1, row2, col1, col2;
  178.     unsigned char *sChars, *sMap, *sMapLimit;
  179.     unsigned char color;
  180.  
  181.     maxLineLength = 1;    /* reset this count */
  182.  
  183.     /* get the corners of the inside of the window */
  184.     row1 = w->row1 + 1;
  185.     col1 = w->col1 + 1 ;
  186.     row2 = w->row2 - 1;
  187.     col2 = w->col2 - 1;
  188.  
  189.     /* fill the rows one at a time */
  190.     cp = w->posTopline;
  191.     n = w->numTopline;
  192.  
  193.     while( row1 <= row2 ) {
  194.         cp = fillLine(w, cp, row1, col1, col2);
  195.         if( doUpdates )
  196.             updateScreen(row1, row1);
  197.         if( cp == -1 )
  198.             break;
  199.         n++;
  200.         row1++;
  201.     }
  202.     if( cp == -1 )
  203.         cp = fileSize(w->fileId);
  204.     w->posBotline = cp;
  205.     w->numBotline = n;
  206.     color = w->textColor;
  207.     while( ++row1 <= row2 ) {
  208.         sMap = screenMap + scrCols*row1 + col1;
  209.         sMapLimit = screenMap + scrCols*row1 + col2;
  210.         sChars = screenChars + (scrCols<<1)*row1 + (col1<<1);
  211.         while( sMap <= sMapLimit ) {
  212.             if( *sMap != 0 ) {
  213.                 *sMap = scrMapReset;
  214.                 *sChars++ = ' ';
  215.                 *sChars++ = color;
  216.             } else
  217.                 sChars += 2;
  218.             ++sMap;
  219.         }
  220.         if( doUpdates )
  221.             updateScreen(row1, row1);
  222.     }
  223. }
  224.  
  225. extern void repword(unsigned int, unsigned char *, int);
  226.  
  227. long pascal
  228. /* XTAG:fillLine */
  229. fillLine(w, cp, row, col1, col2)
  230.     struct window *w;
  231.     long cp;
  232.     int row, col1, col2;
  233. {
  234.     extern struct window *selWindow;
  235.     extern struct window *windowList;
  236.     extern long selBegin, selEnd;
  237.     extern unsigned char msgBuffer[];
  238.     extern int tabWidth;
  239.     extern unsigned char *screenMap;
  240.     extern unsigned char *screenChars;
  241.     extern unsigned char scrMapReset;
  242.     extern int debug;
  243.     extern int invisibleText;
  244.     extern int scrCols;
  245.     extern struct SREGS segRegs;
  246.     extern unsigned char charTable[];
  247.  
  248.     unsigned char ch, nullChar, color;
  249.     unsigned int buf;
  250.     register unsigned char *sMap;
  251.     register unsigned char *sChars;
  252.     unsigned char *sMapLimit;
  253.     unsigned char far *firstByte;
  254.     unsigned char far *lastByte;
  255.     int insertIndex;
  256.     long cp2;
  257.     int tabStop, indent, col;
  258.     int iBuffer, eofFlag;
  259.     unsigned char textAttr, selAttr;
  260.     
  261.     eofFlag = 0;
  262.     insertIndex = -1;
  263.     
  264.     /* for top window optimization */
  265.     buf = (unsigned int)' ' + ( ((unsigned int)w->textColor) << 8 );
  266.  
  267.     /* set up the color codes */
  268.     textAttr = w->textColor;
  269.     selAttr = w->selColor;
  270.     
  271.     /* get the text in the line */
  272.     cp2 = cp;
  273.     firstByte = (unsigned char far *)1;
  274.     lastByte = (unsigned char far *)0;
  275.  
  276.     /* set up for the loop */
  277.     iBuffer = 0;
  278.     col = 0;    /* count columns starting at 0 */
  279.     indent = w->indent;
  280.     sMap = screenMap + scrCols*row + col1;
  281.     sMapLimit = screenMap + scrCols*row + col2;
  282.     sChars = screenChars + (scrCols<<1)*row + (col1<<1);
  283.  
  284.     while( sMap <= sMapLimit ) {
  285.         /* is char at file position cp2 part of the selection? */
  286.         if( w == selWindow && selBegin <= cp2 && cp2 <= selEnd )
  287.             color = selAttr;
  288.         else
  289.             color = textAttr;
  290.         if( firstByte > lastByte ) {
  291.             if(getSpan(w->fileId, cp2, &firstByte, &lastByte,0)){
  292.                 nullChar = 0;  /* end of file */
  293.                 eofFlag = 1;
  294.                 firstByte = &nullChar;
  295.                 lastByte = firstByte;
  296.             }
  297.         }
  298. #ifdef ANASAZI
  299.         if( anasazi
  300.          && insertIndex != -1
  301.          && (ch = insertString[insertIndex]) != '\0' )
  302.             ++insertIndex;
  303.         else
  304. #endif
  305.         ch = *firstByte++;
  306.         ++cp2;
  307.         switch( charTable[ch] ) {
  308.         
  309.         case 1:        /* newline -- end of line  */
  310.             if( col >= indent ) {
  311.                 if( *sMap != 0 ) {
  312.                     *sMap = scrMapReset;
  313.                     *sChars++ = ' ';
  314.                     *sChars++ = color;
  315.                 } else
  316.                     sChars += 2;
  317.                 ++sMap;
  318.             }
  319.             goto endLoop;
  320.  
  321.         case 2:        /* end of file */
  322.             if( !eofFlag ) 
  323.                 goto showChar;
  324.             if( col >= indent ) {
  325.                 if( *sMap != 0 ) {
  326.                     *sMap = scrMapReset;
  327.                     *sChars++ = 4;
  328.                     *sChars++ = color;
  329.                 } else
  330.                     sChars += 2;
  331.                 ++sMap;
  332.             }
  333.             cp2 = -1;    /* indicate end of file written */
  334.             goto endLoop;
  335.  
  336.         case 3:    /* tab */
  337.             tabStop = tabWidth - (col % tabWidth) + col;
  338.             while( col < tabStop )
  339.                 if( col++ >= indent ) {
  340.                     if( *sMap != 0 ) {
  341.                         *sMap = scrMapReset;
  342.                         *sChars++ = ' ';
  343.                         *sChars++ = color;
  344.                     } else
  345.                         sChars += 2;
  346.                     if( ++sMap > sMapLimit )
  347.                         break;
  348.                 }
  349.             break;
  350.  
  351.         case 4:        /* carriage return  */
  352.             /* We want to ignore CRs if the next character is */
  353.             /* a NL. Also show CRs in unixMode (w->state&2==2) */
  354.             if( firstByte > lastByte ) {
  355.                 if( getSpan(w->fileId, cp2, &firstByte,
  356.                             &lastByte, 0) ) {
  357.                     nullChar = 0;  /* end of file */
  358.                     eofFlag = 1;
  359.                     firstByte = &nullChar;
  360.                     lastByte = firstByte;
  361.                 }
  362.             }
  363.             if( *firstByte == '\n' && (w->state&0x2)==0 )
  364.                 break;
  365.             /* we drop through on NL when in unixMode */
  366.             /* else drop through and display the CR */
  367.         case 0:    /* other (one char position) character */
  368.         showChar:
  369.             if( col++ >= indent ) {
  370.                 if( *sMap != 0 ) {
  371.                     *sMap = scrMapReset;
  372.                     *sChars++ = ch;
  373.                     *sChars++ = color;
  374.                 } else
  375.                     sChars += 2;
  376.                 ++sMap;
  377.             }
  378.             break;
  379.  
  380. #ifdef ANASAZI
  381.         case 5:        /* anasazi escape character */
  382.             processBlock(ch, w, insertString, &cp2, &textAttr,
  383.                 &selAttr);
  384.             insertIndex = (insertString[0]=='\0' ? -1 : 0);
  385.             firstByte = (unsigned char far *)1;
  386.             lastByte = (unsigned char far *)0;
  387.             break;
  388. #endif
  389.         }
  390.     }
  391. endLoop:
  392.     /* optimize for the top window */
  393.     if( w == windowList ) {
  394.         indent = sMapLimit - sMap + 1;
  395.         if( indent > 0 ) {
  396.             memset(sMap, scrMapReset, indent);
  397.             repword(buf, sChars, indent);
  398.         }
  399.     } else {
  400.         color = w->textColor;
  401.         while( sMap <= sMapLimit ) {
  402.             if( *sMap != 0 ) {
  403.                 *sMap = scrMapReset;
  404.                 *sChars++ = ' ';
  405.                 *sChars++ = color;
  406.             } else
  407.                 sChars += 2;
  408.             ++sMap;
  409.         }
  410.     }
  411.     /* find the end of the line */
  412.     /* only look if we have not already gotten to EOF */
  413.     if( !eofFlag )
  414.     while( ch != '\n' ) {
  415.         if( firstByte > lastByte ) {
  416.             if( getSpan(w->fileId, cp2,&firstByte, &lastByte, 0) )
  417.                 break;
  418.         }
  419.         ch = *firstByte++;
  420.         if( ch == '\t' )
  421.             col += tabWidth - (col % tabWidth);
  422.         ++col;
  423.         ++cp2;
  424.     }
  425.     /* adjust for the CRLF */
  426.     col -= 2;
  427.     if( col > maxLineLength )
  428.         maxLineLength = col;
  429.     return cp2;
  430. }
  431.  
  432. void pascal
  433. /* XTAG:setMap */
  434. setMap(row1, col1, row2, col2, clear, color)
  435.     /*
  436.      * clear = 0 --> ...............  blank screenChars
  437.      * clear = 1 --> clear screenMap  .................
  438.      * clear = 2 --> clear screenMap  blank screenChars
  439.      */
  440.     int row1, col1, row2, col2, clear, color;
  441. {
  442.     extern unsigned char *screenMap;
  443.     extern unsigned char *screenChars;
  444.     extern unsigned char msgBuffer[];
  445.     extern int scrRows, scrCols;
  446.     extern void repword(unsigned int, unsigned char *, int);
  447.  
  448.     register int i;
  449.     int n, blank;
  450.     unsigned int chars;
  451.  
  452.     if( clear != 0 )
  453.         memset(screenMap, 0, scrRows*scrCols);
  454.     blank = ((clear == 2) || (clear == 0));
  455.     n = col2 - col1 + 1;
  456.     chars = (unsigned int)' ' + ( ((unsigned int)color) << 8);
  457.     for(i = row1; i <= row2; i++) {
  458.         memset(screenMap+scrCols*i+col1, 1, n);
  459.         if( blank )
  460.             repword(chars,screenChars+(scrCols<<1)*i+(col1<<1),n);
  461.     }
  462. }
  463.  
  464. #ifdef SLOWREPMEM
  465. void pascal
  466. /* XTAG:repmem */
  467. repmem(s, v, lv, nv)
  468.     unsigned char *s;
  469.     unsigned char *v;
  470.     int lv, nv;
  471. {
  472.     register int i;
  473.     register unsigned char *vv;
  474.     int j;
  475.     unsigned char ch1, ch2;
  476.  
  477.     if( lv == 2 ) {
  478.         ch1 = *v;
  479.         ch2 = *(v+1);
  480.         for(i = 0; i < nv; ++i) {
  481.             *s++ = ch1;
  482.             *s++ = ch2;
  483.         }
  484.     } else {
  485.         for(i = 0; i < nv; ++i) {
  486.             vv = v;
  487.             for(j = 0; j < lv; ++j)
  488.                 *s++ = *vv++;
  489.         }
  490.     }
  491. }
  492. #endif
  493.  
  494. void pascal
  495. /* XTAG: maskTop */
  496. maskTop(w)
  497.     struct window *w;
  498. {
  499.     extern struct window *windowList;
  500.     extern unsigned char *screenMap;
  501.     extern int scrCols;
  502.  
  503.     register struct window *w1;
  504.     register int i;
  505.     int n, row2, col1, col2;
  506.  
  507.     w1 = windowList;
  508.     while( w1 != w && w1 != NULL ) {
  509.         col1 = w1->col1;
  510.         row2 = w1->row2;
  511.         col2 = w1->col2;
  512.         n = col2 - col1 + 1;
  513.         for(i = w1->row1; i <= row2; i++)
  514.             memset(screenMap+scrCols*i+col1, 0, n);
  515. /* LATER: should this be screenMapReset instead of always 0? */
  516.         w1 = w1->nextWindow;
  517.     }
  518. }
  519.  
  520. void pascal
  521. /* XTAG:displayChar */
  522. displayChar(row, col, ch, attr)
  523.     int row, col, attr;
  524.     unsigned char ch;
  525. {
  526.     extern unsigned char *screenMap;
  527.     extern unsigned char *screenChars;
  528.     extern unsigned int dispMemory;
  529.     extern unsigned char scrMapReset;
  530.     extern int scrCols;
  531.     extern int debug;
  532.  
  533.     register unsigned char *p, *q;
  534.  
  535.     p = screenMap + scrCols*row + col;
  536.     if( *p != 0 ) {
  537.         q = screenChars + (scrCols<<1)*row + (col<<1);
  538.         *q++ = ch;
  539.         *q = (unsigned char)attr;
  540.         *p = scrMapReset;
  541.     }
  542.  
  543. extern void horvid(int, unsigned char *, int);
  544. extern void hor1vid(int, unsigned char *, int);
  545.  
  546. void pascal
  547. /* XTAG:updateScreen */
  548. updateScreen(row1, row2)
  549.     int row1, row2;
  550. {
  551.     extern union REGS rin, rout;
  552.     extern unsigned char *screenChars;
  553.     extern int mousePresent;
  554.     extern unsigned int dispMemory;
  555.     extern int videoMode;
  556.     extern int scrCols;
  557.     extern struct SREGS segRegs;
  558.  
  559.     int row, col, saveCx, saveDx, dupCount, dupCol, *pw;
  560.     unsigned char *p;
  561.  
  562.     switch( videoMode ) {
  563.  
  564.     default:
  565.     case 0:    /* monochrome, just write into the buffer */
  566.     monochrome:
  567.         movedata(segRegs.ds,
  568.             (unsigned int)(screenChars+(scrCols<<1)*row1),
  569.             dispMemory, (scrCols<<1)*row1,
  570.             (scrCols<<1)*(row2-row1+1));
  571.         break;
  572.  
  573.     case 2:    /* color/graphics, write only during horizontal retrace */
  574.         if( dispMemory != 0xB800 )
  575.             goto monochrome;
  576.         horvid((scrCols<<1)*row1, screenChars+(scrCols<<1)*row1,
  577.             scrCols*(row2-row1+1));
  578.         break;
  579.  
  580.     case 3:    /* color/graphics, write only during horizontal retrace */
  581.         if( dispMemory != 0xB800 )
  582.             goto monochrome;
  583.         hor1vid((scrCols<<1)*row1, screenChars+(scrCols<<1)*row1,
  584.             (scrCols<<1)*(row2-row1+1));
  585.         break;
  586.  
  587.     case 1:    /* use BIOS calls */
  588.         /* remember the current mouse cursor position */
  589.         if( mousePresent ) {
  590.             setCType(0x20,0x20);    /* make cursor invisible */
  591.             /* Roy Smith says CX=0x2007 also turns off the cursor */
  592.         } else
  593.             getCPos(&saveCx, &saveDx);
  594.         p = screenChars+(scrCols<<1)*row1;
  595.         rin.h.bh = 0;
  596.         for(row = row1; row <= row2; row++) {
  597.             dupCount = 1;
  598.             dupCol = 0;
  599.             for(col = 0; col < scrCols; col++) {
  600.                 pw = (int *)p;
  601.                 if( *pw != *(pw+1) ) {
  602.                     rin.h.ah = 2;
  603.                     rin.h.dh = (unsigned char)row;
  604.                     rin.h.dl = (unsigned char)dupCol;
  605.                     int86(0x10, &rin, &rout);
  606.                     rin.h.ah = 9;
  607.                     rin.h.al = *p++;
  608.                     rin.h.bl = *p++;
  609.                     rin.x.cx = dupCount;
  610.                     int86(0x10, &rin, &rout);
  611.                     dupCount = 1;
  612.                     dupCol = col + 1;
  613.                 } else {
  614.                     ++dupCount;
  615.                     p += 2;
  616.                 }
  617.             }
  618.         }
  619.         if( mousePresent ) {
  620.             /* reset the cursor */
  621.             if( dispMemory == 0xB000 )
  622.                 setCType(4, 9);
  623.             else
  624.                 setCType(2, 5);
  625.         } else
  626.             setCPos(saveCx, saveDx);
  627.         break;
  628.     }
  629. }
  630.  
  631. void pascal
  632. /* XTAG:updateLine */
  633. updateLine(row1)
  634.     int row1;
  635. {
  636.     extern union REGS rin, rout;
  637.     extern unsigned char screenLine[];
  638.     extern int mousePresent;
  639.     extern unsigned int dispMemory;
  640.     extern int videoMode;
  641.     extern int scrCols;
  642.     extern struct SREGS segRegs;
  643.     extern void horvid(int, unsigned char *, int);
  644.     extern void hor1vid(int, unsigned char *, int);
  645.  
  646.     int row, col, saveCx, saveDx, dupCount, dupCol, *pw;
  647.     unsigned char *p;
  648.  
  649.     switch( videoMode ) {
  650.  
  651.     default:
  652.     case 0:    /* monochrome, just write into the buffer */
  653.     monochrome:
  654.         movedata(segRegs.ds, (unsigned int)screenLine, dispMemory,
  655.             (scrCols<<1)*row1, scrCols<<1 );
  656.         break;
  657.  
  658.     case 2:    /* color/graphics, write only during horizontal retrace */
  659.         if( dispMemory != 0xB800 )
  660.             goto monochrome;
  661.         horvid((scrCols<<1)*row1, screenLine, scrCols);
  662.         break;
  663.  
  664.     case 3:    /* color/graphics, write only during horizontal retrace */
  665.         if( dispMemory != 0xB800 )
  666.             goto monochrome;
  667.         hor1vid((scrCols<<1)*row1, screenLine, scrCols<<1);
  668.         break;
  669.  
  670.     case 1:    /* use BIOS calls */
  671.         /* remember the current mouse cursor position */
  672.         if( mousePresent ) {
  673.             setCType(0x20,0x20);    /* make cursor invisible */
  674.             /* Roy Smith says CX=0x2007 also turns off the cursor */
  675.         } else
  676.             getCPos(&saveCx, &saveDx);
  677.         p = screenLine;
  678.         rin.h.bh = 0;
  679.         /* display the row */
  680.         dupCount = 1;
  681.         dupCol = 0;
  682.         for(col = 0; col < scrCols; col++) {
  683.             pw = (int *)p;
  684.             if( *pw != *(pw+1) ) {
  685.                 rin.h.ah = 2;
  686.                 rin.h.dh = (unsigned char)row;
  687.                 rin.h.dl = (unsigned char)dupCol;
  688.                 int86(0x10, &rin, &rout);
  689.                 rin.h.ah = 9;
  690.                 rin.h.al = *p++;
  691.                 rin.h.bl = *p++;
  692.                 rin.x.cx = dupCount;
  693.                 int86(0x10, &rin, &rout);
  694.                 dupCount = 1;
  695.                 dupCol = col + 1;
  696.             } else {
  697.                 ++dupCount;
  698.                 p += 2;
  699.             }
  700.         }
  701.         if( mousePresent ) {
  702.             /* reset the cursor */
  703.             if( dispMemory == 0xB000 )
  704.                 setCType(4, 9);
  705.             else
  706.                 setCType(2, 5);
  707.         } else
  708.             setCPos(saveCx, saveDx);
  709.         break;
  710.     }
  711. }
  712.  
  713. void pascal
  714. /* XTAG:downScroll */
  715. downScroll(w, nLines)
  716.     register struct window *w;
  717.     int nLines;
  718. {
  719.     extern struct window *activeWindow;
  720.     extern unsigned char border1[], border2[], border3[], border4[];
  721.     extern unsigned char msgBuffer[];
  722.     extern int isMessage;
  723.     extern int debug;
  724.     
  725.     unsigned char *border;
  726.  
  727.     if( nLines <= 0 )
  728.         return;
  729.     w->posTopline = prevLine(w->fileId, w->posTopline, &nLines);
  730.     w->numTopline -= nLines;
  731.     fillWindow(w, 1);
  732.     banner(w);
  733.     if( w != activeWindow )
  734.         border = &border1[0];
  735.     else
  736.         border = &border2[0];
  737.     drawBorder(border, w->row1, w->col1, w->row2, w->col2,
  738.         w->borderColor, 0);
  739.     updateScreen(w->row1, w->row2);
  740.     if( isMessage == 4 )
  741.         msg("", 1);
  742. }
  743.  
  744. void pascal
  745. /* XTAG:upScroll */
  746. upScroll(w, nLines)
  747.     register struct window *w;
  748.     int nLines;
  749. {
  750.     extern struct window *activeWindow;
  751.     extern unsigned char border1[], border2[], border3[], border4[];
  752.     extern unsigned char msgBuffer[];
  753.     extern int isMessage;
  754.     extern int debug;
  755.     
  756.     unsigned char *border;
  757.  
  758.     if( nLines <= 0 )
  759.         return;
  760.     w->posTopline = nextLine(w->fileId, w->posTopline, &nLines);
  761.     w->numTopline += nLines;
  762.     fillWindow(w, 1);
  763.     banner(w);
  764.     if( w != activeWindow )
  765.         border = &border1[0];
  766.     else
  767.         border = &border2[0];
  768.     drawBorder(border, w->row1, w->col1, w->row2, w->col2,
  769.         w->borderColor, 0);
  770.     updateScreen(w->row1, w->row2);
  771.     if( isMessage == 4 )
  772.         msg("", 1);
  773. }
  774.