home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / c / curses / src / wrefresh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-30  |  8.7 KB  |  265 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.9  92/06/21  01:14:13  sie
  42.  * Moved _clear=FALSE to after all lines have been refreshed.
  43.  * 
  44.  * Revision 1.8  92/06/11  00:22:05  sie
  45.  * Now reflects cleared window to curscr.
  46.  * 
  47.  * Revision 1.7  92/06/10  23:45:04  sie
  48.  * Added serial support.
  49.  * 
  50.  * Revision 1.6  92/01/25  23:56:18  sie
  51.  * Now uses FontHeight and FontWidth.
  52.  * 
  53.  * Revision 1.5  91/12/30  10:31:13  sie
  54.  * Removed LRLine and LRATTRS.
  55.  * The speed increase caused by them was too insignificant.
  56.  * 
  57.  * Revision 1.4  91/12/28  22:46:01  sie
  58.  * changed attrs to UBYTE from short + some tidying up.
  59.  * 
  60.  * Revision 1.3  91/12/28  14:01:40  sie
  61.  * Removed WinStat.
  62.  * Renamed LineElement as lnel.
  63.  * 
  64.  * Revision 1.2  91/09/28  17:54:39  sie
  65.  * Only need to optimise lines that have been written to.
  66.  * 
  67.  * Revision 1.1  91/09/07  11:52:07  sie
  68.  * Initial revision
  69.  * 
  70.  *
  71.  */
  72.  
  73. static char *rcsid = "$Header: SRC:lib/curses/src/RCS/wrefresh.c,v 1.9 92/06/21 01:14:13 sie Exp $";
  74.  
  75. #include <exec/types.h>
  76. #include "acurses.h"
  77. #include <proto/graphics.h>
  78. #include <dos.h>
  79. #include <string.h>
  80. #include <fcntl.h>
  81.  
  82.  
  83. static void _optimise(WINDOW *winptr, int line)
  84. {
  85.   int i;
  86.  
  87.   if(!winptr->LnArry[line].Touched)
  88.     return;
  89.  
  90.   for(i=winptr->LnArry[line].StartCol; i<=winptr->LnArry[line].EndCol; i++) {
  91.     if((winptr->LnArry[line].Line[i] !=
  92.     curscr->LnArry[line+winptr->_begy].Line[i+winptr->_begx]) ||
  93.        (winptr->LnArry[line].ATTRS[i] !=
  94.     curscr->LnArry[line+winptr->_begy].ATTRS[i+winptr->_begx]))
  95.       break;
  96.     winptr->LnArry[line].StartCol++;
  97.     if(winptr->LnArry[line].StartCol > winptr->LnArry[line].EndCol)
  98.       break;
  99.   }
  100.   for(i=winptr->LnArry[line].EndCol; i>=winptr->LnArry[line].StartCol; i--) {
  101.     if((winptr->LnArry[line].Line[i] !=
  102.     curscr->LnArry[line+winptr->_begy].Line[i+winptr->_begx]) ||
  103.        (winptr->LnArry[line].ATTRS[i] !=
  104.     curscr->LnArry[line+winptr->_begy].ATTRS[i+winptr->_begx]))
  105.       break;
  106.     winptr->LnArry[line].EndCol--;
  107.     if(winptr->LnArry[line].StartCol > winptr->LnArry[line].EndCol)
  108.       break;
  109.   }
  110.   if(winptr->LnArry[line].StartCol > winptr->LnArry[line].EndCol)
  111.     winptr->LnArry[line].Touched = FALSE;
  112. }
  113.  
  114. wrefresh(WINDOW *WinPtr)
  115. {
  116.   int i, j;
  117.   unsigned long style;
  118.   short Line;
  119.   char Buffer[BUFSIZ];
  120.  
  121.  
  122.   if(WinPtr == curscr)
  123.     clearok(WinPtr, TRUE);
  124.   ZapCursor();
  125.   /*
  126.    *  It is possible for no printing since last refresh, but for
  127.    *  a move to have been done...
  128.    */
  129.   if(WinPtr->_flags & CWF_MOVED) {
  130.     WinPtr->_flags &= ~CWF_MOVED;
  131.     CursorLine = WinPtr->_cury + WinPtr->_begy;
  132.     CursorCol = WinPtr->_curx + WinPtr->_begx;
  133.   }
  134.   if(WinPtr->_clear) {
  135.     if(CursesType == CUST_CURSES) {
  136.       SetAPen(RPort, 0);
  137.       SetDrMd(RPort, JAM2);
  138.       RectFill(RPort, WinPtr->_begx * FontWidth, WinPtr->_begy * FontHeight,
  139.            ((WinPtr->_begx + WinPtr->_maxx) * FontWidth) + (FontWidth-1),
  140.            ((WinPtr->_begy + WinPtr->_maxy) * FontHeight + (FontHeight-1)));
  141.     } else if(CursesType == ANSI_CURSES) {
  142.       ANSIClearRect(WinPtr->_begy, WinPtr->_begx, WinPtr->_maxy+1, WinPtr->_maxx+1);
  143.     }
  144.     /* update curscr */
  145.     for(i=0; i<=WinPtr->_maxy; i++) {
  146.       memset(&(curscr->LnArry[i+WinPtr->_begy].Line[WinPtr->_begx]), ' ',
  147.          WinPtr->_maxx+1);
  148.       memset(&(curscr->LnArry[i+WinPtr->_begy].ATTRS[WinPtr->_begx]), COLOR_WHITE,
  149.          WinPtr->_maxx+1);
  150.     }
  151.   }
  152.   if(CursesFlags & CFLAG_CURSOR) {
  153.     CursorLine = WinPtr->_cury + WinPtr->_begy;
  154.     CursorCol = WinPtr->_curx + WinPtr->_begx;
  155.   }
  156.   for(Line=0; Line<WinPtr->NLines; Line++) {
  157.     chkabort(); /* Check if INTR */
  158.     /* if we have cleared the screen then must refresh everything */
  159.     if(WinPtr->_clear) {
  160.       WinPtr->LnArry[Line].Touched = TRUE;
  161.       WinPtr->LnArry[Line].StartCol = 0;
  162.       WinPtr->LnArry[Line].EndCol = WinPtr->_maxx;
  163.     }
  164.     _optimise(WinPtr, Line);    /* don't refresh stuff that's already done */
  165.     if(WinPtr->LnArry[Line].Touched) {
  166.       j = WinPtr->LnArry[Line].StartCol;
  167.       for(i=j + 1; i<=WinPtr->LnArry[Line].EndCol; i++) {
  168.     if(WinPtr->LnArry[Line].ATTRS[i] != WinPtr->LnArry[Line].ATTRS[j]) {
  169.       /* Print what we've got */
  170.       if(CursesType == CUST_CURSES) {
  171.         SetAPen(RPort, WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART);
  172.         if(WinPtr->LnArry[Line].ATTRS[j] & (A_REVERSE | A_STANDOUT))
  173.           SetDrMd(RPort, JAM2|INVERSVID);
  174.         else
  175.           SetDrMd(RPort, JAM2);
  176.         style = FS_NORMAL;
  177.         if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  178.           style |= FSF_BOLD;
  179.         if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  180.           style |= FSF_UNDERLINED;
  181.         SetSoftStyle(RPort, style, ~0L);
  182.         Move(RPort, (j+WinPtr->_begx) * FontWidth,
  183.          FontBase + (Line+WinPtr->_begy) * FontHeight);
  184.         Text(RPort, &WinPtr->LnArry[Line].Line[j], i-j);
  185.       } else if(CursesType == ANSI_CURSES) {
  186.         ANSIMove(Line+WinPtr->_begy, j+WinPtr->_begx);
  187.         if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART) {
  188.           sprintf(Buffer, "\033[0;%d;40m", (WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART)+30);
  189.           if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  190.         Buffer[2] = '1';
  191.           if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  192.         Buffer[2] = '4';
  193.           if(WinPtr->LnArry[Line].ATTRS[j] & A_STANDOUT)
  194.         Buffer[2] = '7';
  195.           write(1, Buffer, strlen(Buffer));
  196.         }
  197.         write(1, &WinPtr->LnArry[Line].Line[j], i-j);
  198.         if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART)
  199.           write(1, "\033[0m", 4);
  200.       }
  201.       /*
  202.        *  Update the record of the current screen state.
  203.        */
  204.       if(WinPtr != curscr) {
  205.         memcpy(&(curscr->LnArry[Line+WinPtr->_begy].Line[j+WinPtr->_begx]),
  206.            &WinPtr->LnArry[Line].Line[j], i-j);
  207.         memcpy(&(curscr->LnArry[Line+WinPtr->_begy].ATTRS[j+WinPtr->_begx]),
  208.            &WinPtr->LnArry[Line].ATTRS[j], i-j);
  209.       }
  210.       j=i;
  211.     }
  212.       }
  213.       if(j<i) {
  214.     if(CursesType == CUST_CURSES) {
  215.       SetAPen(RPort, WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART);
  216.       if(WinPtr->LnArry[Line].ATTRS[j] & (A_STANDOUT | A_REVERSE))
  217.         SetDrMd(RPort, JAM2|INVERSVID);
  218.       else
  219.         SetDrMd(RPort, JAM2);
  220.       style = FS_NORMAL;
  221.       if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  222.         style |= FSF_BOLD;
  223.       if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  224.         style |= FSF_UNDERLINED;
  225.       SetSoftStyle(RPort, style, ~0L);
  226.       Move(RPort, (j+WinPtr->_begx) * FontWidth,
  227.            FontBase + (Line+WinPtr->_begy) * FontHeight);
  228.       Text(RPort, &(WinPtr->LnArry[Line].Line[j]), i-j);
  229.     } else if(CursesType == ANSI_CURSES) {
  230.       ANSIMove(Line+WinPtr->_begy, j+WinPtr->_begx);
  231.       if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART) {
  232.         sprintf(Buffer, "\033[0;%d;40m", (WinPtr->LnArry[Line].ATTRS[j] & A_CLRPART)+30);
  233.         if(WinPtr->LnArry[Line].ATTRS[j] & A_BOLD)
  234.           Buffer[2] = '1';
  235.         if(WinPtr->LnArry[Line].ATTRS[j] & A_UNDERLINE)
  236.           Buffer[2] = '4';
  237.         if(WinPtr->LnArry[Line].ATTRS[j] & A_STANDOUT)
  238.           Buffer[2] = '7';
  239.         write(1, Buffer, strlen(Buffer));
  240.       }
  241.       write(1, &WinPtr->LnArry[Line].Line[j], i-j);
  242.       if(WinPtr->LnArry[Line].ATTRS[j] & A_ATRPART)
  243.         write(1, "\033[0m", 4);
  244.     }
  245.     /*
  246.      *  Update the record of the current screen state.
  247.      */
  248.     if(WinPtr != curscr) {
  249.       memcpy(&(curscr->LnArry[Line+WinPtr->_begy].Line[j+WinPtr->_begx]),
  250.          &WinPtr->LnArry[Line].Line[j], i-j);
  251.       memcpy(&(curscr->LnArry[Line+WinPtr->_begy].ATTRS[j+WinPtr->_begx]),
  252.          &WinPtr->LnArry[Line].ATTRS[j], i-j);
  253.     }
  254.       }
  255.       WinPtr->LnArry[Line].Touched = FALSE;
  256.       WinPtr->LnArry[Line].StartCol = WinPtr->_maxx;
  257.       WinPtr->LnArry[Line].EndCol = 0;
  258.     }
  259.   }
  260.   DrawCursor();
  261.   if(WinPtr->_clear)        /* Only on this refresh is it OK to clear */
  262.     WinPtr->_clear = FALSE;
  263.   return OK;
  264. }
  265.