home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / c / curses / src / wrefresh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  9.0 KB  |  275 lines

  1. /* -*-C-*-
  2.  *
  3.  *
  4.  * Filename : wrefresh.c
  5.  *
  6.  * Author   : Simon J Raybould.    (sie@fulcrum.bt.co.uk).
  7.  *
  8.  * Date     : Friday 23rd August 1991.
  9.  *
  10.  * Desc     : Refresh a window, sending output to the screen.
  11.  *
  12.  *
  13.  * THIS CODE IS NOT PUBLIC DOMAIN
  14.  * ==============================
  15.  * 
  16.  * This code is copyright Simon J Raybould 1991, all rights are reserved.
  17.  * All code, ideas, data structures and algorithms remain the property of the
  18.  * author. Neither the whole nor sections of this code may be used as part
  19.  * of other code without the authors consent. If you wish to use some of this
  20.  * code then please email me at (sie@fulcrum.bt.co.uk).
  21.  *
  22.  * This source is not public domain, so you do not have any right to alter it
  23.  * or sell it for personal gain. The source is provided purely for reference
  24.  * purposes. You may re-compile the source with any compiler you choose.
  25.  * You must not distribute altered copies without the authors consent. My
  26.  * intention is that the source will help people isolate any bugs much more
  27.  * effectivly.
  28.  *
  29.  * Disclaimer
  30.  * ==========
  31.  *
  32.  * No implication is made as to this code being fit for any purpose at all.
  33.  * I (the author) shall not be held responsible for any loss of data or damage 
  34.  * to property that may result from its use or misuse.
  35.  *
  36.  *
  37.  * Revision History
  38.  * ================
  39.  *
  40.  * $Log: wrefresh.c,v $
  41.  * Revision 1.11  1993/05/17  23:33:10  sie
  42.  * Underscores added to names.
  43.  * Changes for version 2.10
  44.  *
  45.  * Revision 1.10  1992/12/25  23:39:56  sie
  46.  * GNU C port.
  47.  *
  48.  * Revision 1.9  92/06/21  01:14:13  sie
  49.  * Moved _clear=FALSE to after all lines have been refreshed.
  50.  * 
  51.  * Revision 1.8  92/06/11  00:22:05  sie
  52.  * Now reflects cleared window to curscr.
  53.  * 
  54.  * Revision 1.7  92/06/10  23:45:04  sie
  55.  * Added serial support.
  56.  * 
  57.  * Revision 1.6  92/01/25  23:56:18  sie
  58.  * Now uses FontHeight and FontWidth.
  59.  * 
  60.  * Revision 1.5  91/12/30  10:31:13  sie
  61.  * Removed LRLine and LRATTRS.
  62.  * The speed increase caused by them was too insignificant.
  63.  * 
  64.  * Revision 1.4  91/12/28  22:46:01  sie
  65.  * changed attrs to UBYTE from short + some tidying up.
  66.  * 
  67.  * Revision 1.3  91/12/28  14:01:40  sie
  68.  * Removed WinStat.
  69.  * Renamed LineElement as lnel.
  70.  * 
  71.  * Revision 1.2  91/09/28  17:54:39  sie
  72.  * Only need to optimise lines that have been written to.
  73.  * 
  74.  * Revision 1.1  91/09/07  11:52:07  sie
  75.  * Initial revision
  76.  * 
  77.  *
  78.  */
  79.  
  80. static char *rcsid = "$Header: /SRC/lib/curses/src/RCS/wrefresh.c,v 1.11 1993/05/17 23:33:10 sie Exp $";
  81.  
  82. #include <exec/types.h>
  83. #include "acurses.h"
  84. #include <string.h>
  85. #include <fcntl.h>
  86.  
  87.  
  88. static void _optimise(WINDOW *winptr, int line)
  89. {
  90.   int i;
  91.  
  92.   if(!winptr->LnArry[line].Touched)
  93.     return;
  94.  
  95.   for(i=winptr->LnArry[line].StartCol; i<=winptr->LnArry[line].EndCol; i++) {
  96.     if((winptr->LnArry[line].Line[i] !=
  97.     curscr->LnArry[line+winptr->_begy].Line[i+winptr->_begx]) ||
  98.        (winptr->LnArry[line].ATTRS[i] !=
  99.     curscr->LnArry[line+winptr->_begy].ATTRS[i+winptr->_begx]))
  100.       break;
  101.     winptr->LnArry[line].StartCol++;
  102.     if(winptr->LnArry[line].StartCol > winptr->LnArry[line].EndCol)
  103.       break;
  104.   }
  105.   for(i=winptr->LnArry[line].EndCol; i>=winptr->LnArry[line].StartCol; i--) {
  106.     if((winptr->LnArry[line].Line[i] !=
  107.     curscr->LnArry[line+winptr->_begy].Line[i+winptr->_begx]) ||
  108.        (winptr->LnArry[line].ATTRS[i] !=
  109.     curscr->LnArry[line+winptr->_begy].ATTRS[i+winptr->_begx]))
  110.       break;
  111.     winptr->LnArry[line].EndCol--;
  112.     if(winptr->LnArry[line].StartCol > winptr->LnArry[line].EndCol)
  113.       break;
  114.   }
  115.   if(winptr->LnArry[line].StartCol > winptr->LnArry[line].EndCol) {
  116.     winptr->LnArry[line].StartCol = winptr->_maxx+1;
  117.     winptr->LnArry[line].EndCol = 0;
  118.     winptr->LnArry[line].Touched = FALSE;
  119.   }
  120. }
  121.  
  122. wrefresh(WINDOW *WinPtr)
  123. {
  124.   int i, j;
  125.   unsigned long style;
  126.   short Line;
  127.   char Buffer[BUFSIZ];
  128.  
  129.  
  130.   if(WinPtr == curscr)
  131.     clearok(WinPtr, TRUE);
  132.   _ZapCursor();
  133.   /*
  134.    *  It is possible for no printing since last refresh, but for
  135.    *  a move to have been done...
  136.    */
  137.   if(WinPtr->_flags & CWF_MOVED) {
  138.     WinPtr->_flags &= ~CWF_MOVED;
  139.     _CursorLine = WinPtr->_cury + WinPtr->_begy;
  140.     _CursorCol = WinPtr->_curx + WinPtr->_begx;
  141.   }
  142.   if(WinPtr->_clear) {
  143.     if(_CursesType == CUST_CURSES) {
  144.       SetAPen(_RPort, 0);
  145.       SetDrMd(_RPort, JAM2);
  146.       RectFill(_RPort, WinPtr->_begx * _FontWidth, WinPtr->_begy * _FontHeight,
  147.            ((WinPtr->_begx + WinPtr->_maxx) * _FontWidth) + (_FontWidth-1),
  148.            ((WinPtr->_begy + WinPtr->_maxy) * _FontHeight + (_FontHeight-1)));
  149.     } else if(_CursesType == ANSI_CURSES) {
  150.       _ANSIClearRect(WinPtr->_begy, WinPtr->_begx, WinPtr->_maxy+1, WinPtr->_maxx+1);
  151.     }
  152.     /* update curscr */
  153.     for(i=0; i<=WinPtr->_maxy; i++) {
  154.       memset(&(curscr->LnArry[i+WinPtr->_begy].Line[WinPtr->_begx]), ' ',
  155.          WinPtr->_maxx+1);
  156.       memset(&(curscr->LnArry[i+WinPtr->_begy].ATTRS[WinPtr->_begx]), COLOR_WHITE,
  157.          WinPtr->_maxx+1);
  158.     }
  159.   }
  160.   if(_CursesFlags & CFLAG_CURSOR) {
  161.     _CursorLine = WinPtr->_cury + WinPtr->_begy;
  162.     _CursorCol = WinPtr->_curx + WinPtr->_begx;
  163.   }
  164.   for(Line=0; Line<WinPtr->NLines; Line++) {
  165. #ifdef LATTICE
  166.     chkabort(); /* Check if INTR */
  167. #endif
  168.     /* if we have cleared the screen then must refresh everything */
  169.     if(WinPtr->_clear) {
  170.       WinPtr->LnArry[Line].Touched = TRUE;
  171.       WinPtr->LnArry[Line].StartCol = 0;
  172.       WinPtr->LnArry[Line].EndCol = WinPtr->_maxx;
  173.     }
  174.     _optimise(WinPtr, Line);    /* don't refresh stuff that's already done */
  175.     if(WinPtr->LnArry[Line].Touched) {
  176.       j = WinPtr->LnArry[Line].StartCol;
  177.       for(i=j + 1; i<=WinPtr->LnArry[Line].EndCol; i++) {
  178.     if(WinPtr->LnArry[Line].ATTRS[i] != WinPtr->LnArry[Line].ATTRS[j]) {
  179.       /* Print what we've got */
  180.       if(_CursesType == CUST_CURSES) {
  181.         SetAPen(_RPort, WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART);
  182.         if(WinPtr->LnArry[Line].ATTRS[j] & (A_REVERSE | A_STANDOUT))
  183.           SetDrMd(_RPort, JAM2|INVERSVID);
  184.         else
  185.           SetDrMd(_RPort, JAM2);
  186.         style = FS_NORMAL;
  187.         if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  188.           style |= FSF_BOLD;
  189.         if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  190.           style |= FSF_UNDERLINED;
  191.         SetSoftStyle(_RPort, style, ~0L);
  192.         Move(_RPort, (j+WinPtr->_begx) * _FontWidth,
  193.          _FontBase + (Line+WinPtr->_begy) * _FontHeight);
  194.         Text(_RPort, &WinPtr->LnArry[Line].Line[j], i-j);
  195.       } else if(_CursesType == ANSI_CURSES) {
  196.         _ANSIMove(Line+WinPtr->_begy, j+WinPtr->_begx);
  197.         if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART) {
  198.           sprintf(Buffer, "\033[0;%d;40m", (WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART)+30);
  199.           if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  200.         Buffer[2] = '1';
  201.           if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  202.         Buffer[2] = '4';
  203.           if(WinPtr->LnArry[Line].ATTRS[j] & A_STANDOUT)
  204.         Buffer[2] = '7';
  205.           write(1, Buffer, strlen(Buffer));
  206.         }
  207.         write(1, &WinPtr->LnArry[Line].Line[j], i-j);
  208.         if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART)
  209.           write(1, "\033[0m", 4);
  210.       }
  211.       /*
  212.        *  Update the record of the current screen state.
  213.        */
  214.       if(WinPtr != curscr) {
  215.         memcpy(&(curscr->LnArry[Line+WinPtr->_begy].Line[j+WinPtr->_begx]),
  216.            &WinPtr->LnArry[Line].Line[j], i-j);
  217.         memcpy(&(curscr->LnArry[Line+WinPtr->_begy].ATTRS[j+WinPtr->_begx]),
  218.            &WinPtr->LnArry[Line].ATTRS[j], i-j);
  219.       }
  220.       j=i;
  221.     }
  222.       }
  223.       if(j<i) {
  224.     if(_CursesType == CUST_CURSES) {
  225.       SetAPen(_RPort, WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART);
  226.       if(WinPtr->LnArry[Line].ATTRS[j] & (A_STANDOUT | A_REVERSE))
  227.         SetDrMd(_RPort, JAM2|INVERSVID);
  228.       else
  229.         SetDrMd(_RPort, JAM2);
  230.       style = FS_NORMAL;
  231.       if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  232.         style |= FSF_BOLD;
  233.       if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  234.         style |= FSF_UNDERLINED;
  235.       SetSoftStyle(_RPort, style, ~0L);
  236.       Move(_RPort, (j+WinPtr->_begx) * _FontWidth,
  237.            _FontBase + (Line+WinPtr->_begy) * _FontHeight);
  238.       Text(_RPort, &(WinPtr->LnArry[Line].Line[j]), i-j);
  239.     } else if(_CursesType == ANSI_CURSES) {
  240.       _ANSIMove(Line+WinPtr->_begy, j+WinPtr->_begx);
  241.       if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART) {
  242.         sprintf(Buffer, "\033[0;%d;40m", (WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART)+30);
  243.         if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  244.           Buffer[2] = '1';
  245.         if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  246.           Buffer[2] = '4';
  247.         if(WinPtr->LnArry[Line].ATTRS[j] & A_STANDOUT)
  248.           Buffer[2] = '7';
  249.         write(1, Buffer, strlen(Buffer));
  250.       }
  251.       write(1, &WinPtr->LnArry[Line].Line[j], i-j);
  252.       if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART)
  253.         write(1, "\033[0m", 4);
  254.     }
  255.     /*
  256.      *  Update the record of the current screen state.
  257.      */
  258.     if(WinPtr != curscr) {
  259.       memcpy(&(curscr->LnArry[Line+WinPtr->_begy].Line[j+WinPtr->_begx]),
  260.          &WinPtr->LnArry[Line].Line[j], i-j);
  261.       memcpy(&(curscr->LnArry[Line+WinPtr->_begy].ATTRS[j+WinPtr->_begx]),
  262.          &WinPtr->LnArry[Line].ATTRS[j], i-j);
  263.     }
  264.       }
  265.       WinPtr->LnArry[Line].Touched = FALSE;
  266.       WinPtr->LnArry[Line].StartCol = WinPtr->_maxx+1;
  267.       WinPtr->LnArry[Line].EndCol = 0;
  268.     }
  269.   }
  270.   _DrawCursor();
  271.   if(WinPtr->_clear)        /* Only on this refresh is it OK to clear */
  272.     WinPtr->_clear = FALSE;
  273.   return OK;
  274. }
  275.