ncurses 4.2
[ncurses.git] / ncurses / lib_addch.c
index e2e58190cca1edcfc653f96334e8eb6f464792ab..859c9caa652e081b23e0c32e309890d9c374a152 100644 (file)
@@ -1,66 +1,47 @@
-
-/***************************************************************************
-*                            COPYRIGHT NOTICE                              *
-****************************************************************************
-*                ncurses is copyright (C) 1992-1995                        *
-*                          Zeyd M. Ben-Halim                               *
-*                          zmbenhal@netcom.com                             *
-*                          Eric S. Raymond                                 *
-*                          esr@snark.thyrsus.com                           *
-*                                                                          *
-*        Permission is hereby granted to reproduce and distribute ncurses  *
-*        by any means and for any fee, whether alone or as part of a       *
-*        larger distribution, in source or in binary form, PROVIDED        *
-*        this notice is included with any such distribution, and is not    *
-*        removed from any of its header files. Mention of ncurses in any   *
-*        applications linked with it is highly appreciated.                *
-*                                                                          *
-*        ncurses comes AS IS with no warranty, implied or expressed.       *
-*                                                                          *
-***************************************************************************/
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc.                        *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
+ *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ ****************************************************************************/
 
 /*
 **     lib_addch.c
 **
-**     The routines waddch(), wattr_on(), wattr_off(), wchgat().
+**     The routine waddch().
 **
 */
 
 #include <curses.priv.h>
 #include <ctype.h>
 
-MODULE_ID("$Id: lib_addch.c,v 1.30 1997/04/12 17:45:55 tom Exp $")
-
-int wattr_on(WINDOW *win, const attr_t at)
-{
-       T((T_CALLED("wattr_on(%p,%s)"), win, _traceattr(at)));
-       T(("... current %s", _traceattr(win->_attrs)));
-       toggle_attr_on(win->_attrs,at);
-       returnCode(OK);
-}
-
-int wattr_off(WINDOW *win, const attr_t at)
-{
-       T((T_CALLED("wattr_off(%p,%s)"), win, _traceattr(at)));
-       T(("... current %s", _traceattr(win->_attrs)));
-       toggle_attr_off(win->_attrs,at);
-       returnCode(OK);
-}
-
-int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts GCC_UNUSED)
-{
-    int        i;
-
-    T((T_CALLED("wchgat(%p,%d,%s,%d)"), win, n, _traceattr(attr), color));
-
-    toggle_attr_on(attr,COLOR_PAIR(color));
-
-    for (i = win->_curx; i <= win->_maxx && (n == -1 || (n-- > 0)); i++)
-       win->_line[win->_cury].text[i]
-           = ch_or_attr(TextOf(win->_line[win->_cury].text[i]),attr);
-
-    returnCode(OK);
-}
+MODULE_ID("$Id: lib_addch.c,v 1.39 1998/02/11 12:13:57 tom Exp $")
 
 /*
  * Ugly microtweaking alert.  Everything from here to end of module is
@@ -72,14 +53,29 @@ int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts GCC_UN
  * window sync hook, for use by string-put functions.
  */
 
+/* Return bit mask for clearing color pair number if given ch has color */
+#define COLOR_MASK(ch) (~(chtype)((ch)&A_COLOR?A_COLOR:0))
+
 static inline chtype render_char(WINDOW *win, chtype ch)
 /* compute a rendition of the given char correct for the current context */
 {
-       if (TextOf(ch) == ' ')
-               ch = ch_or_attr(ch, win->_bkgd);
-       else if (!(ch & A_ATTRIBUTES))
-               ch = ch_or_attr(ch, (win->_bkgd & A_ATTRIBUTES));
-       TR(TRACE_VIRTPUT, ("bkg = %#lx -> ch = %#lx", win->_bkgd, ch));
+       chtype a = win->_attrs;
+       
+       if (ch == ' ')
+       {
+               /* color in attrs has precedence over bkgd */
+               ch = a | (win->_bkgd & COLOR_MASK(a));
+       }
+       else
+       {
+               /* color in attrs has precedence over bkgd */
+               a |= (win->_bkgd & A_ATTRIBUTES) & COLOR_MASK(a);
+               /* color in ch has precedence */
+               ch |= (a & COLOR_MASK(ch));
+       }
+
+       TR(TRACE_VIRTPUT, ("bkg = %lx, attrs = %lx -> ch = %lx", win->_bkgd,
+               win->_attrs, ch));
 
        return(ch);
 }
@@ -87,18 +83,17 @@ static inline chtype render_char(WINDOW *win, chtype ch)
 chtype _nc_background(WINDOW *win)
 /* make render_char() visible while still allowing us to inline it below */
 {
-    return(render_char(win, BLANK));
+       return (win->_bkgd);
 }
 
 chtype _nc_render(WINDOW *win, chtype ch)
 /* make render_char() visible while still allowing us to inline it below */
 {
-    chtype c = render_char(win,ch);
-    return (ch_or_attr(c,win->_attrs));
+       return render_char(win, ch);
 }
 
 /* check if position is legal; if not, return error */
-#ifdef NDEBUG                  /* treat this like an assertion */
+#ifndef NDEBUG                 /* treat this like an assertion */
 #define CHECK_POSITION(win, x, y) \
        if (y > win->_maxy \
         || x > win->_maxx \
@@ -116,12 +111,12 @@ chtype _nc_render(WINDOW *win, chtype ch)
 static inline
 int waddch_literal(WINDOW *win, chtype ch)
 {
-register int x, y;
+       int x;
+       struct ldat *line;
 
        x = win->_curx;
-       y = win->_cury;
 
-       CHECK_POSITION(win, x, y);
+       CHECK_POSITION(win, x, win->_cury);
 
        /*
         * If we're trying to add a character at the lower-right corner more
@@ -134,21 +129,20 @@ register int x, y;
        }
 
        ch = render_char(win, ch);
-       ch = ch_or_attr(ch,win->_attrs);
        TR(TRACE_VIRTPUT, ("win attr = %s", _traceattr(win->_attrs)));
 
-       if (win->_line[y].text[x] != ch) {
-               if (win->_line[y].firstchar == _NOCHANGE)
-                       win->_line[y].firstchar = win->_line[y].lastchar = x;
-               else if (x < win->_line[y].firstchar)
-                       win->_line[y].firstchar = x;
-               else if (x > win->_line[y].lastchar)
-                       win->_line[y].lastchar = x;
-
-       }
-
-       win->_line[y].text[x++] = ch;
-       TR(TRACE_VIRTPUT, ("(%d, %d) = %s", y, x, _tracechtype(ch)));
+       line = win->_line+win->_cury;
+       
+       if (line->firstchar == _NOCHANGE)
+               line->firstchar = line->lastchar = x;
+       else if (x < line->firstchar)
+               line->firstchar = x;
+       else if (x > line->lastchar)
+               line->lastchar = x;
+
+       line->text[x++] = ch;
+       
+       TR(TRACE_VIRTPUT, ("(%d, %d) = %s", win->_cury, x, _tracechtype(ch)));
        if (x > win->_maxx) {
                /*
                 * The _WRAPPED flag is useful only for telling an application
@@ -161,42 +155,37 @@ register int x, y;
                 * add a character to the lower-right corner.
                 */
                win->_flags |= _WRAPPED;
-               if (++y > win->_regbottom) {
-                       y = win->_regbottom;
-                       x = win->_maxx;
-                       if (win->_scroll)
-                               scroll(win);
-                       else {
-                               win->_curx = x;
-                               win->_cury = y;
+               if (++win->_cury > win->_regbottom) {
+                       win->_cury = win->_regbottom;
+                       win->_curx = win->_maxx;
+                       if (!win->_scroll)
                                return (ERR);
-                       }
+                       scroll(win);
                }
-               x = 0;
+               win->_curx = 0;
+               return (OK);
        }
-
        win->_curx = x;
-       win->_cury = y;
-
        return OK;
 }
 
 static inline
-int waddch_nosync(WINDOW *win, const chtype c)
+int waddch_nosync(WINDOW *win, const chtype ch)
 /* the workhorse function -- add a character to the given window */
 {
-register chtype        ch = c;
-register int   x, y;
+       int     x, y;
+       int     t;
+       const char *s;
+
+       if ((ch & A_ALTCHARSET)
+           || ((t = TextOf(ch)) > 127)
+           || ((s = unctrl(t))[1] == 0))
+               return waddch_literal(win, ch);
 
        x = win->_curx;
        y = win->_cury;
 
-       CHECK_POSITION(win, x, y);
-
-       if (ch & A_ALTCHARSET)
-               goto noctrl;
-
-       switch ((int)TextOf(ch)) {
+       switch (t) {
        case '\t':
                x += (TABSIZE-(x%TABSIZE));
 
@@ -206,8 +195,9 @@ register int        x, y;
                 */
                if ((! win->_scroll && (y == win->_regbottom))
                 || (x <= win->_maxx)) {
+                       chtype blank = (' ' | AttrOf(ch));
                        while (win->_curx < x) {
-                               if (waddch_literal(win, (' ' | AttrOf(ch))) == ERR)
+                               if (waddch_literal(win, blank) == ERR)
                                        return(ERR);
                        }
                        break;
@@ -241,18 +231,16 @@ register int      x, y;
                win->_flags &= ~_WRAPPED;
                break;
        case '\b':
-               if (x > 0) {
-                       x--;
-                       win->_flags &= ~_WRAPPED;
-               }
+               if (x == 0)
+                       return (OK);
+               x--;
+               win->_flags &= ~_WRAPPED;
                break;
        default:
-               if (is7bits(TextOf(ch)) && iscntrl(TextOf(ch)))
-                       return(waddstr(win, unctrl((unsigned char)ch)));
-
-               /* FALLTHRU */
-       noctrl:
-               return waddch_literal(win, ch);
+               while (*s)
+                       if (waddch_literal(win, (*s++)|AttrOf(ch)) == ERR)
+                               return ERR;
+               return(OK);
        }
 
        win->_curx = x;
@@ -281,7 +269,7 @@ int waddch(WINDOW *win, const chtype ch)
 
        TR(TRACE_VIRTPUT|TRACE_CCALLS, (T_CALLED("waddch(%p, %s)"), win, _tracechtype(ch)));
 
-       if (waddch_nosync(win, ch) != ERR)
+       if (win && (waddch_nosync(win, ch) != ERR))
        {
                _nc_synchook(win);
                code = OK;
@@ -297,7 +285,7 @@ int wechochar(WINDOW *win, const chtype ch)
 
        TR(TRACE_VIRTPUT|TRACE_CCALLS, (T_CALLED("wechochar(%p, %s)"), win, _tracechtype(ch)));
 
-       if (waddch_literal(win, ch) != ERR)
+       if (win && (waddch_nosync(win, ch) != ERR))
        {
                bool    save_immed = win->_immed;
                win->_immed = TRUE;