]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/base/lib_addch.c
ncurses 5.3
[ncurses.git] / ncurses / base / lib_addch.c
index 69c17c34709bf0cd43cde2177ab3570efa3677ea..5b41fedf3a2c851bfb3b47b0b881531104804fe0 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2001,2002 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            *
  * authorization.                                                           *
  ****************************************************************************/
 
-/****************************************************************************
- *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
- *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
- ****************************************************************************/
-
 /*
 **     lib_addch.c
 **
@@ -41,7 +36,7 @@
 #include <curses.priv.h>
 #include <ctype.h>
 
-MODULE_ID("$Id: lib_addch.c,v 1.44 2000/05/20 21:13:11 tom Exp $")
+MODULE_ID("$Id: lib_addch.c,v 1.68 2002/09/28 17:48:13 tom Exp $")
 
 /*
  * Ugly microtweaking alert.  Everything from here to end of module is
@@ -54,39 +49,35 @@ MODULE_ID("$Id: lib_addch.c,v 1.44 2000/05/20 21:13:11 tom Exp $")
  */
 
 /* Return bit mask for clearing color pair number if given ch has color */
-#define COLOR_MASK(ch) (~(chtype)((ch)&A_COLOR?A_COLOR:0))
+#define COLOR_MASK(ch) (~(attr_t)((ch)&A_COLOR?A_COLOR:0))
 
-static inline chtype
-render_char(WINDOW *win, chtype ch)
+static inline NCURSES_CH_T
+render_char(WINDOW *win, NCURSES_CH_T ch)
 /* compute a rendition of the given char correct for the current context */
 {
-    chtype a = win->_attrs;
+    attr_t a = win->_attrs;
 
-    if (ch == ' ') {
-       /* color in attrs has precedence over bkgd */
-       ch = a | (win->_bkgd & COLOR_MASK(a));
+    if (ISBLANK(ch) && AttrOf(ch) == A_NORMAL) {
+       /* color in attrs has precedence over bkgrnd */
+       ch = win->_nc_bkgd;
+       SetAttr(ch, a | (AttrOf(win->_nc_bkgd) & COLOR_MASK(a)));
     } else {
-       /* color in attrs has precedence over bkgd */
-       a |= (win->_bkgd & A_ATTRIBUTES) & COLOR_MASK(a);
+       /* color in attrs has precedence over bkgrnd */
+       a |= AttrOf(win->_nc_bkgd) & COLOR_MASK(a);
        /* color in ch has precedence */
-       ch |= (a & COLOR_MASK(ch));
+       AddAttr(ch, (a & COLOR_MASK(AttrOf(ch))));
     }
 
-    TR(TRACE_VIRTPUT, ("bkg = %lx, attrs = %lx -> ch = %lx", win->_bkgd,
-           win->_attrs, ch));
+    TR(TRACE_VIRTPUT, ("bkg = %s, attrs = %s -> ch = %s",
+                      _tracech_t2(1, CHREF(win->_nc_bkgd)),
+                      _traceattr(win->_attrs),
+                      _tracech_t2(3, CHREF(ch))));
 
     return (ch);
 }
 
-chtype
-_nc_background(WINDOW *win)
-/* make render_char() visible while still allowing us to inline it below */
-{
-    return (win->_bkgd);
-}
-
-chtype
-_nc_render(WINDOW *win, chtype ch)
+NCURSES_EXPORT(NCURSES_CH_T)
+_nc_render(WINDOW *win, NCURSES_CH_T ch)
 /* make render_char() visible while still allowing us to inline it below */
 {
     return render_char(win, ch);
@@ -109,7 +100,7 @@ _nc_render(WINDOW *win, chtype ch)
 #endif
 
 static inline int
-waddch_literal(WINDOW *win, chtype ch)
+waddch_literal(WINDOW *win, NCURSES_CH_T ch)
 {
     int x;
     struct ldat *line;
@@ -122,7 +113,7 @@ waddch_literal(WINDOW *win, chtype ch)
      * If we're trying to add a character at the lower-right corner more
      * than once, fail.  (Moving the cursor will clear the flag).
      */
-#if 0  /* Solaris 2.6 allows updating the corner more than once */
+#if 0                          /* Solaris 2.6 allows updating the corner more than once */
     if (win->_flags & _WRAPPED) {
        if (x >= win->_maxx)
            return (ERR);
@@ -137,9 +128,39 @@ waddch_literal(WINDOW *win, chtype ch)
 
     CHANGED_CELL(line, x);
 
+    /*
+     * Handle non-spacing characters
+     */
+    if_WIDEC({
+       if (wcwidth(CharOf(ch)) == 0) {
+           int i;
+           int y;
+           if ((x > 0 && ((y = win->_cury) >= 0))
+               || ((y = win->_cury - 1) >= 0 &&
+                   (x = win->_maxx) > 0)) {
+               wchar_t *chars = (win->_line[y].text[x - 1].chars);
+               for (i = 0; i < CCHARW_MAX; ++i) {
+                   if (chars[i] == 0) {
+                       chars[i] = CharOf(ch);
+                       break;
+                   }
+               }
+           }
+           goto testwrapping;
+       }
+    });
     line->text[x++] = ch;
+    /*
+     * Provide for multi-column characters
+     */
+    if_WIDEC({
+       if (wcwidth(CharOf(ch)) > 1)
+           AddAttr(line->text[x++], WA_NAC);
+    }
+  testwrapping:
+    );
 
-    TR(TRACE_VIRTPUT, ("(%d, %d) = %s", win->_cury, x, _tracechtype(ch)));
+    TR(TRACE_VIRTPUT, ("(%d, %d) = %s", win->_cury, x, _tracech_t(CHREF(ch))));
     if (x > win->_maxx) {
        /*
         * The _WRAPPED flag is useful only for telling an application that
@@ -167,15 +188,15 @@ waddch_literal(WINDOW *win, chtype ch)
 }
 
 static inline int
-waddch_nosync(WINDOW *win, const chtype ch)
+waddch_nosync(WINDOW *win, const NCURSES_CH_T ch)
 /* the workhorse function -- add a character to the given window */
 {
     int x, y;
-    int t = 0;
+    chtype t = 0;
     const char *s = 0;
 
-    if ((ch & A_ALTCHARSET)
-       || ((t = TextOf(ch)) > 127)
+    if ((AttrOf(ch) & A_ALTCHARSET)
+       || ((t = CharOf(ch)) > 127)
        || ((s = unctrl(t))[1] == 0))
        return waddch_literal(win, ch);
 
@@ -192,7 +213,8 @@ waddch_nosync(WINDOW *win, const chtype ch)
         */
        if ((!win->_scroll && (y == win->_regbottom))
            || (x <= win->_maxx)) {
-           chtype blank = (' ' | AttrOf(ch));
+           NCURSES_CH_T blank = NewChar2(BLANK_TEXT, BLANK_ATTR);
+           AddAttr(blank, AttrOf(ch));
            while (win->_curx < x) {
                if (waddch_literal(win, blank) == ERR)
                    return (ERR);
@@ -234,9 +256,12 @@ waddch_nosync(WINDOW *win, const chtype ch)
        win->_flags &= ~_WRAPPED;
        break;
     default:
-       while (*s)
-           if (waddch_literal(win, (*s++) | AttrOf(ch)) == ERR)
+       while (*s) {
+           NCURSES_CH_T sch;
+           SetChar(sch, *s++, AttrOf(ch));
+           if (waddch_literal(win, sch) == ERR)
                return ERR;
+       }
        return (OK);
     }
 
@@ -246,8 +271,8 @@ waddch_nosync(WINDOW *win, const chtype ch)
     return (OK);
 }
 
-int
-_nc_waddch_nosync(WINDOW *win, const chtype c)
+NCURSES_EXPORT(int)
+_nc_waddch_nosync(WINDOW *win, const NCURSES_CH_T c)
 /* export copy of waddch_nosync() so the string-put functions can use it */
 {
     return (waddch_nosync(win, c));
@@ -261,15 +286,17 @@ _nc_waddch_nosync(WINDOW *win, const chtype c)
 
 /* These are actual entry points */
 
-int
+NCURSES_EXPORT(int)
 waddch(WINDOW *win, const chtype ch)
 {
     int code = ERR;
+    NCURSES_CH_T wch;
+    SetChar2(wch, ch);
 
     TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("waddch(%p, %s)"), win,
-           _tracechtype(ch)));
+                                     _tracechtype(ch)));
 
-    if (win && (waddch_nosync(win, ch) != ERR)) {
+    if (win && (waddch_nosync(win, wch) != ERR)) {
        _nc_synchook(win);
        code = OK;
     }
@@ -278,15 +305,54 @@ waddch(WINDOW *win, const chtype ch)
     return (code);
 }
 
-int
+NCURSES_EXPORT(int)
 wechochar(WINDOW *win, const chtype ch)
 {
     int code = ERR;
+    NCURSES_CH_T wch;
+    SetChar2(wch, ch);
 
     TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wechochar(%p, %s)"), win,
-           _tracechtype(ch)));
+                                     _tracechtype(ch)));
+
+    if (win && (waddch_nosync(win, wch) != ERR)) {
+       bool save_immed = win->_immed;
+       win->_immed = TRUE;
+       _nc_synchook(win);
+       win->_immed = save_immed;
+       code = OK;
+    }
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
+    return (code);
+}
+
+#if USE_WIDEC_SUPPORT
+NCURSES_EXPORT(int)
+wadd_wch(WINDOW *win, const cchar_t * wch)
+{
+    int code = ERR;
+
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wadd_wch(%p, %s)"), win,
+                                     _tracech_t(wch)));
+
+    if (win && (waddch_nosync(win, *wch) != ERR)) {
+       _nc_synchook(win);
+       code = OK;
+    }
+
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
+    return (code);
+}
+
+NCURSES_EXPORT(int)
+wecho_wchar(WINDOW *win, const cchar_t * wch)
+{
+    int code = ERR;
+
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wecho_wchar(%p, %s)"), win,
+                                     _tracech_t(wch)));
 
-    if (win && (waddch_nosync(win, ch) != ERR)) {
+    if (win && (waddch_nosync(win, *wch) != ERR)) {
        bool save_immed = win->_immed;
        win->_immed = TRUE;
        _nc_synchook(win);
@@ -296,3 +362,4 @@ wechochar(WINDOW *win, const chtype ch)
     TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
     return (code);
 }
+#endif /* USE_WIDEC_SUPPORT */