Change-Id: If881ec130833c7e7e62caa3d31e350a531f5bc8e Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-on: http://review.coreboot.org/12398 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
		
			
				
	
	
		
			409 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			409 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 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
 |