BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.bin / tn3270 / sys_curses / termout.c
index f058015..f456c64 100644 (file)
@@ -1,22 +1,38 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
  * All rights reserved.
  *
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)termout.c  3.7 (Berkeley) %G%";
+static char sccsid[] = "@(#)termout.c  4.3 (Berkeley) 4/26/91";
 #endif /* not lint */
 
 #if defined(unix)
 #endif /* not lint */
 
 #if defined(unix)
@@ -45,6 +61,7 @@ static char sccsid[] = "@(#)termout.c 3.7 (Berkeley) %G%";
 #include "../ctlr/declare.h"
 #include "../ctlr/oia.h"
 #include "../ctlr/screen.h"
 #include "../ctlr/declare.h"
 #include "../ctlr/oia.h"
 #include "../ctlr/screen.h"
+#include "../ctlr/scrnctlr.h"
 
 #include "../general/globals.h"
 
 
 #include "../general/globals.h"
 
@@ -182,15 +199,34 @@ static void
 #endif /* defined(NOT43) */
 SlowScreen()
 {
 #endif /* defined(NOT43) */
 SlowScreen()
 {
+    register int is, shouldbe, isattr, shouldattr;
     register int pointer;
     register int pointer;
-    register int c;
-    register int fieldattr;
+    register int fieldattr, termattr;
     register int columnsleft;
 
     register int columnsleft;
 
-#   define  SetHighlightMode(p) { \
-               if (!IsStartField(p) && IsHighlightedAttr(fieldattr)) { \
+#define        NORMAL          0               
+#define        HIGHLIGHT       1               /* Mask bits */
+#define        NONDISPLAY      4               /* Mask bits */
+#define        UNDETERMINED    8               /* Mask bits */
+
+#define        DoAttributes(x) \
+           switch (x&ATTR_DSPD_MASK) { \
+           case ATTR_DSPD_NONDISPLAY: \
+               x = NONDISPLAY; \
+               break; \
+           case ATTR_DSPD_HIGH: \
+               x = HIGHLIGHT; \
+               break; \
+           default: \
+               x = 0; \
+               break; \
+           }
+
+#   define  SetHighlightMode(x) \
+           { \
+               if ((x)&HIGHLIGHT) { \
                    if (!inHighlightMode) { \
                    if (!inHighlightMode) { \
-                       inHighlightMode = 1; \
+                       inHighlightMode = HIGHLIGHT; \
                        standout(); \
                    } \
                } else { \
                        standout(); \
                    } \
                } else { \
@@ -202,10 +238,8 @@ SlowScreen()
            }
 
 #   define  DoCharacterAt(c,p) { \
            }
 
 #   define  DoCharacterAt(c,p) { \
-               SetTerminal(p, c); \
                if (p != HighestScreen()) { \
                if (p != HighestScreen()) { \
-                   c = TerminalCharacterAttr(disp_asc[c&0xff], p, \
-                                                               fieldattr); \
+                   c = disp_asc[c&0xff]; \
                    if (terminalCursorAddress != p) { \
                        if (ERR == mvaddch(ScreenLine(p), \
                                                ScreenLineOffset(p), c)) {\
                    if (terminalCursorAddress != p) { \
                        if (ERR == mvaddch(ScreenLine(p), \
                                                ScreenLineOffset(p), c)) {\
@@ -271,7 +305,8 @@ SlowScreen()
            pointer += (bunequal(Host+pointer, Terminal+pointer,
                        (Highest-pointer+1)*sizeof Host[0])/sizeof Host[0]);
 
            pointer += (bunequal(Host+pointer, Terminal+pointer,
                        (Highest-pointer+1)*sizeof Host[0])/sizeof Host[0]);
 
-               /* how many characters to change until the end of the
+               /*
+                * How many characters to change until the end of the
                 * current line
                 */
            columnsleft = NumberColumns - ScreenLineOffset(pointer);
                 * current line
                 */
            columnsleft = NumberColumns - ScreenLineOffset(pointer);
@@ -281,137 +316,131 @@ SlowScreen()
            move(ScreenLine(pointer), ScreenLineOffset(pointer));
 
                /* what is the field attribute of the current position */
            move(ScreenLine(pointer), ScreenLineOffset(pointer));
 
                /* what is the field attribute of the current position */
-           fieldattr = FieldAttributes(WhereAttrByte(pointer));
+           if (FormattedScreen()) {
+               fieldattr = FieldAttributes(pointer);
+               DoAttributes(fieldattr);
+           } else {
+               fieldattr = NORMAL;
+           }
+           if (TerminalFormattedScreen()) {
+               termattr = TermAttributes(pointer);
+               DoAttributes(termattr);
+           } else {
+               termattr = NORMAL;
+           }
 
 
-           if ((IsStartField(pointer) != TermIsStartField(pointer)) ||
-                   (IsStartField(pointer) &&
-                       fieldattr != TermAttributes(pointer))) {
+           SetHighlightMode(fieldattr);
+           /*
+            * The following will terminate at least when we get back
+            * to the original 'pointer' location (since we force
+            * things to be equal).
+            */
+           for (;;) {
+               if (IsStartField(pointer)) {
+                   shouldbe = DISP_BLANK;
+                   shouldattr = 0;
+                   fieldattr = GetHost(pointer);
+                   DoAttributes(fieldattr);
+               } else {
+                   if (fieldattr&NONDISPLAY) {
+                       shouldbe = DISP_BLANK;
+                   } else {
+                       shouldbe = GetHost(pointer);
+                   }
+                   shouldattr = fieldattr;
+               }
+               if (TermIsStartField(pointer)) {
+                   is = DISP_BLANK;
+                   isattr = 0;
+                   termattr = UNDETERMINED; /* Need to find out AFTER update */
+               } else {
+                   if (termattr&NONDISPLAY) {
+                       is = DISP_BLANK;
+                   } else {
+                       is = GetTerminal(pointer);
+                   }
+                   isattr = termattr;
+               }
+               if ((shouldbe == is) && (shouldattr == isattr)
+                       && (GetHost(pointer) == GetTerminal(pointer))
+                       && (GetHost(ScreenInc(pointer))
+                                       == GetTerminal(ScreenInc(pointer)))) {
+                   break;
+               }
 
 
-               int oldterm;
+               if (shouldattr^inHighlightMode) {
+                   SetHighlightMode(shouldattr);
+               }
 
 
-               oldterm = TermAttributes(pointer);
+               DoCharacterAt(shouldbe, pointer);
                if (IsStartField(pointer)) {
                if (IsStartField(pointer)) {
-                   TermNewField(pointer, fieldattr);
-                   SetTerminal(pointer, 0);
+                   TermNewField(pointer, FieldAttributes(pointer));
+                   termattr = GetTerminal(pointer);
+                   DoAttributes(termattr);
                } else {
                } else {
-                   TermDeleteField(pointer);
-               }
-                   /* We always do the first character in a divergent
-                    * field, since otherwise the start of a field in
-                    * the Host structure may leave a highlighted blank
-                    * on the screen, and the start of a field in the
-                    * Terminal structure may leave a non-highlighted
-                    * something in the middle of a highlighted field
-                    * on the screen.
+                   SetTerminal(pointer, GetHost(pointer));
+                   /*
+                    * If this USED to be a start field location,
+                    * recompute the terminal attributes.
                     */
                     */
-               SetHighlightMode(pointer);
-               c = GetHost(pointer);
-               DoCharacterAt(c,pointer);               /* MACRO */
-
-               if (NotVisuallyCompatibleAttributes
-                               (pointer, fieldattr, oldterm)) {
-                   int j;
-
-                   j = pointer;
-
-                   pointer = ScreenInc(pointer);
-                   if (!(--columnsleft)) {
-                       DoARefresh();
-                       EmptyTerminal();
-                       move(ScreenLine(pointer), 0);
-                       columnsleft = NumberColumns;
-                   }
-                   SetHighlightMode(pointer);  /* Turn on highlighting */
-                   while ((!IsStartField(pointer)) &&
-                               (!TermIsStartField(pointer))) {
-                       c = GetHost(pointer);
-                       DoCharacterAt(c,pointer);       /* MACRO */
-                       pointer = ScreenInc(pointer);
-                       if (!(--columnsleft)) {
-                           DoARefresh();
-                           EmptyTerminal();
-                           move(ScreenLine(pointer), 0);
-                           columnsleft = NumberColumns;
-                               /* We don't look at HaveInput here, since
-                                * if we leave this loop before the end of
-                                * the 3270 field, we could have pointer
-                                * higher than Highest.  This would cause
-                                * us to end the highest "while" loop,
-                                * but we may, in fact, need to go around the
-                                * screen once again.
-                                */
-                       }
-                       /*              The loop needs to be protected
-                        *      from the situation where there had been only
-                        *      one field on the Terminal, and none on the Host.
-                        *      In this case, we have just deleted our last
-                        *      field.  Hence, the break.
-                        */
-                       if (j == pointer) {
-                           break;
+                   if (termattr == UNDETERMINED) {
+                       termattr = WhereTermAttrByte(pointer);
+                       if ((termattr != 0) || TermIsStartField(0)) {
+                           termattr = GetTerminal(termattr);
+                           DoAttributes(termattr);
+                       } else {        /* Unformatted screen */
+                           termattr = NORMAL;
                        }
                    }
                        }
                    }
-                   if (IsStartField(pointer) && !TermIsStartField(pointer)) {
-                           /* Remember what the terminal looked like */
-                       TermNewField(pointer, oldterm);
-                           /*
-                            * The danger here is that the current position may
-                            * be the start of a Host field.  If so, and the
-                            * field is highlighted, and our terminal was
-                            * highlighted, then we will leave a highlighted
-                            * blank at this position.
-                            */
-                       SetHighlightMode(pointer);
-                       c = GetHost(pointer);
-                       DoCharacterAt(c,pointer);
-                   }
-                       /* We could be in the situation of needing to exit.
-                        * This could happen if the current field wrapped around
-                        * the end of the screen.
-                        */
-                   if (j > pointer) {
+               }
+               pointer = ScreenInc(pointer);
+               if (!(--columnsleft)) {
+                   DoARefresh();
+                   EmptyTerminal();
+                   if (HaveInput) {    /* if input came in, take it */
+                       int c, j;
+
                        /*
                        /*
-                        * pointer is guaranteed to be higher than Highest...
+                        * We need to start a new terminal field
+                        * at this location iff the terminal attributes
+                        * of this location are not what we have had
+                        * them as (ie: we've overwritten the terminal
+                        * start field, a the previous field had different
+                        * display characteristics).
                         */
                         */
-                       pointer = Highest+1;    /* We did the highest thing */
-                       break;
-                   }
-               } else {
-                   c = GetHost(pointer);
-                       /* We always do the first character in a divergent
-                        * field, since otherwise the start of a field in
-                        * the Host structure may leave a highlighted blank
-                        * on the screen, and the start of a field in the
-                        * Terminal structure may leave a non-highlighted
-                        * something in the middle of a highlighted field
-                        * on the screen.
-                        */
-                   SetHighlightMode(pointer);
-                   DoCharacterAt(c,pointer);
-               }
-           } else {
-               SetHighlightMode(pointer);
-               /*
-                * The following will terminate at least when we get back
-                * to the original 'pointer' location (since we force
-                * things to be equal).
-                */
-               while (((c = GetHost(pointer)) != GetTerminal(pointer)) &&
-                       !IsStartField(pointer) && !TermIsStartField(pointer)) {
-                   DoCharacterAt(c, pointer);
-                   pointer = ScreenInc(pointer);
-                   if (!(--columnsleft)) {
-                       DoARefresh();
-                       EmptyTerminal();
-                       if (HaveInput) {        /* if input came in, take it */
-                           break;
+
+                       isattr = TermAttributes(pointer);
+                       DoAttributes(isattr);
+                       if ((!TermIsStartField(pointer)) &&
+                                       (isattr != termattr)) {
+                           /*
+                            * Since we are going to leave a new field
+                            * at this terminal position, we
+                            * need to make sure that we get an actual
+                            * non-highlighted blank on the screen.
+                            */
+                           if ((is != DISP_BLANK) || (termattr&HIGHLIGHT)) {
+                               SetHighlightMode(0);    /* Turn off highlight */
+                               c = ScreenInc(pointer);
+                               j = DISP_BLANK;
+                               DoCharacterAt(j, c);
+                           }
+                           if (termattr&HIGHLIGHT) {
+                               termattr = ATTR_DSPD_HIGH;
+                           } else if (termattr&NONDISPLAY) {
+                               termattr = ATTR_DSPD_NONDISPLAY;
+                           } else {
+                               termattr = 0;
+                           }
+                           TermNewField(pointer, termattr);
                        }
                        }
-                       move(ScreenLine(pointer), 0);
-                       columnsleft = NumberColumns;
+                       break;
                    }
                    }
+                   move(ScreenLine(pointer), 0);
+                   columnsleft = NumberColumns;
                }
                }
-           }
-       }
+           }   /* end of for (;;) */
+       } /* end of while (...) */
     }
     DoARefresh();
     Lowest = pointer;
     }
     DoARefresh();
     Lowest = pointer;
@@ -523,11 +552,12 @@ FastScreen()
                    *tmp++ = 0;                 /* close out */
                    addstr((char *)tmpbuf);
                    tmp = tmpbuf;
                    *tmp++ = 0;                 /* close out */
                    addstr((char *)tmpbuf);
                    tmp = tmpbuf;
-                   tmpend = tmpbuf + NumberColumns - ScreenLineOffset(p-Host);
+                   tmpend = tmpbuf+NumberColumns-ScreenLineOffset(p-Host)-1;
                }
                }
+               standend();
+               addch(' ');
                fieldattr = FieldAttributesPointer(p);  /* Get attributes */
                DoAttribute(fieldattr); /* Set standout, non-display */
                fieldattr = FieldAttributesPointer(p);  /* Get attributes */
                DoAttribute(fieldattr); /* Set standout, non-display */
-               *tmp++ = ' ';
            } else {
                if (fieldattr) {        /* Should we display? */
                                /* Display translated data */
            } else {
                if (fieldattr) {        /* Should we display? */
                                /* Display translated data */