pdcurses/addch.c

changeset 97
2d43f05b284c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pdcurses/addch.c	Thu Jul 23 18:07:39 2015 +0300
@@ -0,0 +1,408 @@
+/* Public Domain Curses */
+
+#include <curspriv.h>
+
+RCSID("$Id: addch.c,v 1.54 2008/07/13 16:08:17 wmcbrine Exp $")
+
+/*man-start**************************************************************
+
+  Name:                                                         addch
+
+  Synopsis:
+        int addch(const chtype ch);
+        int waddch(WINDOW *win, const chtype ch);
+        int mvaddch(int y, int x, const chtype ch);
+        int mvwaddch(WINDOW *win, int y, int x, const chtype ch);
+        int echochar(const chtype ch);
+        int wechochar(WINDOW *win, const chtype ch);
+
+        int addrawch(chtype ch);
+        int waddrawch(WINDOW *win, chtype ch);
+        int mvaddrawch(int y, int x, chtype ch);
+        int mvwaddrawch(WINDOW *win, int y, int x, chtype ch);
+
+        int add_wch(const cchar_t *wch);
+        int wadd_wch(WINDOW *win, const cchar_t *wch);
+        int mvadd_wch(int y, int x, const cchar_t *wch);
+        int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch);
+        int echo_wchar(const cchar_t *wch);
+        int wecho_wchar(WINDOW *win, const cchar_t *wch);
+
+  Description:
+        addch() adds the chtype ch to the default window (stdscr) at the
+        current cursor position, and advances the cursor. Note that
+        chtypes can convey both text (a single character) and
+        attributes, including a color pair. add_wch() is the wide-
+        character version of this function, taking a pointer to a
+        cchar_t instead of a chtype.
+
+        waddch() is like addch(), but also lets you specify the window.
+        (This is in fact the core output routine.) wadd_wch() is the
+        wide version.
+
+        mvaddch() moves the cursor to the specified (y, x) position, and
+        adds ch to stdscr. mvadd_wch() is the wide version.
+
+        mvwaddch() moves the cursor to the specified position and adds 
+        ch to the specified window. mvwadd_wch() is the wide version.
+
+        echochar() adds ch to stdscr at the current cursor position and 
+        calls refresh(). echo_wchar() is the wide version.
+
+        wechochar() adds ch to the specified window and calls 
+        wrefresh(). wecho_wchar() is the wide version.
+
+        addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are
+        PDCurses-specific wrappers for addch() etc. that disable the 
+        translation of control characters.
+
+        The following applies to all these functions:
+
+        If the cursor moves on to the right margin, an automatic newline 
+        is performed.  If scrollok is enabled, and a character is added 
+        to the bottom right corner of the window, the scrolling region 
+        will be scrolled up one line.  If scrolling is not allowed, ERR 
+        will be returned.
+
+        If ch is a tab, newline, or backspace, the cursor will be moved 
+        appropriately within the window.  If ch is a newline, the 
+        clrtoeol routine is called before the cursor is moved to the 
+        beginning of the next line.  If newline mapping is off, the 
+        cursor will be moved to the next line, but the x coordinate will 
+        be unchanged.  If ch is a tab the cursor is moved to the next 
+        tab position within the window.  If ch is another control 
+        character, it will be drawn in the ^X notation.  Calling the 
+        inch() routine after adding a control character returns the 
+        representation of the control character, not the control 
+        character.
+
+        Video attributes can be combined with a character by ORing them 
+        into the parameter. Text, including attributes, can be copied 
+        from one place to another by using inch() and addch().
+
+        Note that in PDCurses, for now, a cchar_t and a chtype are the
+        same. The text field is 16 bits wide, and is treated as Unicode
+        (UCS-2) when PDCurses is built with wide-character support
+        (define PDC_WIDE). So, in functions that take a chtype, like
+        addch(), both the wide and narrow versions will handle Unicode.
+        But for portability, you should use the wide functions.
+
+  Return Value:
+        All functions return OK on success and ERR on error.
+
+  Portability                                X/Open    BSD    SYS V
+        addch                                   Y       Y       Y
+        waddch                                  Y       Y       Y
+        mvaddch                                 Y       Y       Y
+        mvwaddch                                Y       Y       Y
+        echochar                                Y       -      3.0
+        wechochar                               Y       -      3.0
+        addrawch                                -       -       -
+        waddrawch                               -       -       -
+        mvaddrawch                              -       -       -
+        mvwaddrawch                             -       -       -
+        add_wch                                 Y
+        wadd_wch                                Y
+        mvadd_wch                               Y
+        mvwadd_wch                              Y
+        echo_wchar                              Y
+        wecho_wchar                             Y
+
+**man-end****************************************************************/
+
+int waddch(WINDOW *win, const chtype ch)
+{
+    int x, y;
+    chtype text, attr;
+    bool xlat;
+
+    PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
+             win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
+
+    if (!win)
+        return ERR;
+
+    x = win->_curx;
+    y = win->_cury;
+
+    if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
+        return ERR;
+
+    xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
+    text = ch & A_CHARTEXT;
+    attr = ch & A_ATTRIBUTES;
+
+    if (xlat && (text < ' ' || text == 0x7f))
+    {
+        int x2;
+
+        switch (text)
+        {
+        case '\t':
+            for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
+            {
+                if (waddch(win, attr | ' ') == ERR)
+                    return ERR;
+
+                /* if tab to next line, exit the loop */
+
+                if (!win->_curx)
+                    break;
+            }
+            return OK;
+
+        case '\n':
+            /* if lf -> crlf */
+
+            if (!SP->raw_out)
+                x = 0;
+
+            wclrtoeol(win);
+
+            if (++y > win->_bmarg)
+            {
+                y--;
+
+                if (wscrl(win, 1) == ERR)
+                    return ERR;
+            }
+
+            break;
+
+        case '\b':
+            /* don't back over left margin */
+
+            if (--x < 0)
+        case '\r':
+                x = 0;
+
+            break;
+
+        case 0x7f:
+            if (waddch(win, attr | '^') == ERR)
+                return ERR;
+
+            return waddch(win, attr | '?');
+
+        default:
+            /* handle control chars */
+
+            if (waddch(win, attr | '^') == ERR)
+                return ERR;
+
+            return waddch(win, ch + '@');
+        }
+    }
+    else
+    {
+        /* If the incoming character doesn't have its own attribute,
+           then use the current attributes for the window. If it has
+           attributes but not a color component, OR the attributes to
+           the current attributes for the window. If it has a color
+           component, use the attributes solely from the incoming
+           character. */
+
+        if (!(attr & A_COLOR))
+            attr |= win->_attrs;
+
+        /* wrs (4/10/93): Apply the same sort of logic for the window 
+           background, in that it only takes precedence if other color 
+           attributes are not there and that the background character 
+           will only print if the printing character is blank. */
+
+        if (!(attr & A_COLOR))
+            attr |= win->_bkgd & A_ATTRIBUTES;
+        else
+            attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
+
+        if (text == ' ')
+            text = win->_bkgd & A_CHARTEXT;
+
+        /* Add the attribute back into the character. */
+
+        text |= attr;
+
+        /* Only change _firstch/_lastch if the character to be added is
+           different from the character/attribute that is already in
+           that position in the window. */
+
+        if (win->_y[y][x] != text)
+        {
+            if (win->_firstch[y] == _NO_CHANGE)
+                win->_firstch[y] = win->_lastch[y] = x;
+            else
+                if (x < win->_firstch[y])
+                    win->_firstch[y] = x;
+                else
+                    if (x > win->_lastch[y])
+                        win->_lastch[y] = x;
+
+            win->_y[y][x] = text;
+        }
+
+        if (++x >= win->_maxx)
+        {
+            /* wrap around test */
+
+            x = 0;
+
+            if (++y > win->_bmarg)
+            {
+                y--;
+
+                if (wscrl(win, 1) == ERR)
+                {
+                    PDC_sync(win);
+                    return ERR;
+                }
+            }
+        }
+    }
+
+    win->_curx = x;
+    win->_cury = y;
+
+    if (win->_immed)
+        wrefresh(win);
+    if (win->_sync)
+        wsyncup(win);
+
+    return OK;
+}
+
+int addch(const chtype ch)
+{
+    PDC_LOG(("addch() - called: ch=%x\n", ch));
+
+    return waddch(stdscr, ch);
+}
+
+int mvaddch(int y, int x, const chtype ch)
+{
+    PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch));
+
+    if (move(y,x) == ERR)
+        return ERR;
+
+    return waddch(stdscr, ch);
+}
+
+int mvwaddch(WINDOW *win, int y, int x, const chtype ch)
+{
+    PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch));
+
+    if (wmove(win, y, x) == ERR)
+        return ERR;
+
+    return waddch(win, ch);
+}
+
+int echochar(const chtype ch)
+{
+    PDC_LOG(("echochar() - called: ch=%x\n", ch));
+
+    return wechochar(stdscr, ch);
+}
+
+int wechochar(WINDOW *win, const chtype ch)
+{
+    PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch));
+
+    if (waddch(win, ch) == ERR)
+        return ERR;
+
+    return wrefresh(win);
+}
+
+int waddrawch(WINDOW *win, chtype ch)
+{
+    PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
+             win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
+
+    if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
+        ch |= A_ALTCHARSET;
+
+    return waddch(win, ch);
+}
+
+int addrawch(chtype ch)
+{
+    PDC_LOG(("addrawch() - called: ch=%x\n", ch));
+
+    return waddrawch(stdscr, ch);
+}
+
+int mvaddrawch(int y, int x, chtype ch)
+{
+    PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch));
+
+    if (move(y, x) == ERR)
+        return ERR;
+
+    return waddrawch(stdscr, ch);
+}
+
+int mvwaddrawch(WINDOW *win, int y, int x, chtype ch)
+{
+    PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n",
+             win, y, x, ch));
+
+    if (wmove(win, y, x) == ERR)
+        return ERR;
+
+    return waddrawch(win, ch);
+}
+
+#ifdef PDC_WIDE
+int wadd_wch(WINDOW *win, const cchar_t *wch)
+{
+    PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch));
+
+    return wch ? waddch(win, *wch) : ERR;
+}
+
+int add_wch(const cchar_t *wch)
+{
+    PDC_LOG(("add_wch() - called: wch=%x\n", *wch));
+
+    return wadd_wch(stdscr, wch);
+}
+
+int mvadd_wch(int y, int x, const cchar_t *wch)
+{
+    PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch));
+
+    if (move(y,x) == ERR)
+        return ERR;
+
+    return wadd_wch(stdscr, wch);
+}
+
+int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch)
+{
+    PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n",
+             win, y, x, *wch));
+
+    if (wmove(win, y, x) == ERR)
+        return ERR;
+
+    return wadd_wch(win, wch);
+}
+
+int echo_wchar(const cchar_t *wch)
+{
+    PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch));
+
+    return wecho_wchar(stdscr, wch);
+}
+
+int wecho_wchar(WINDOW *win, const cchar_t *wch)
+{
+    PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch));
+
+    if (!wch || (wadd_wch(win, wch) == ERR))
+        return ERR;
+
+    return wrefresh(win);
+}
+#endif

mercurial