/* PDCurses */12#include <curspriv.h>34/*man-start**************************************************************56addch7-----89### Synopsis1011int addch(const chtype ch);12int waddch(WINDOW *win, const chtype ch);13int mvaddch(int y, int x, const chtype ch);14int mvwaddch(WINDOW *win, int y, int x, const chtype ch);15int echochar(const chtype ch);16int wechochar(WINDOW *win, const chtype ch);1718int addrawch(chtype ch);19int waddrawch(WINDOW *win, chtype ch);20int mvaddrawch(int y, int x, chtype ch);21int mvwaddrawch(WINDOW *win, int y, int x, chtype ch);2223int add_wch(const cchar_t *wch);24int wadd_wch(WINDOW *win, const cchar_t *wch);25int mvadd_wch(int y, int x, const cchar_t *wch);26int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch);27int echo_wchar(const cchar_t *wch);28int wecho_wchar(WINDOW *win, const cchar_t *wch);2930### Description3132addch() adds the chtype ch to the default window (stdscr) at the33current cursor position, and advances the cursor. Note that chtypes34can convey both text (a single character) and attributes, including a35color pair. add_wch() is the wide-character version of this function,36taking a pointer to a cchar_t instead of a chtype.3738waddch() is like addch(), but also lets you specify the window. (This39is in fact the core output routine.) wadd_wch() is the wide version.4041mvaddch() moves the cursor to the specified (y, x) position, and adds42ch to stdscr. mvadd_wch() is the wide version.4344mvwaddch() moves the cursor to the specified position and adds ch to45the specified window. mvwadd_wch() is the wide version.4647echochar() adds ch to stdscr at the current cursor position and calls48refresh(). echo_wchar() is the wide version.4950wechochar() adds ch to the specified window and calls wrefresh().51wecho_wchar() is the wide version.5253addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are PDCurses-54specific wrappers for addch() etc. that disable the translation of55control characters.5657The following applies to all these functions:5859If the cursor moves on to the right margin, an automatic newline is60performed. If scrollok is enabled, and a character is added to the61bottom right corner of the window, the scrolling region will be62scrolled up one line. If scrolling is not allowed, ERR will be63returned.6465If ch is a tab, newline, or backspace, the cursor will be moved66appropriately within the window. If ch is a newline, the clrtoeol67routine is called before the cursor is moved to the beginning of the68next line. If newline mapping is off, the cursor will be moved to69the next line, but the x coordinate will be unchanged. If ch is a70tab the cursor is moved to the next tab position within the window.71If ch is another control character, it will be drawn in the ^X72notation. Calling the inch() routine after adding a control73character returns the representation of the control character, not74the control character.7576Video attributes can be combined with a character by ORing them into77the parameter. Text, including attributes, can be copied from one78place to another by using inch() and addch().7980Note that in PDCurses, for now, a cchar_t and a chtype are the same.81The text field is 16 bits wide, and is treated as Unicode (UCS-2)82when PDCurses is built with wide-character support (define PDC_WIDE).83So, in functions that take a chtype, like addch(), both the wide and84narrow versions will handle Unicode. But for portability, you should85use the wide functions.8687### Return Value8889All functions return OK on success and ERR on error.9091### Portability92X/Open ncurses NetBSD93addch Y Y Y94waddch Y Y Y95mvaddch Y Y Y96mvwaddch Y Y Y97echochar Y Y Y98wechochar Y Y Y99add_wch Y Y Y100wadd_wch Y Y Y101mvadd_wch Y Y Y102mvwadd_wch Y Y Y103echo_wchar Y Y Y104wecho_wchar Y Y Y105addrawch - - -106waddrawch - - -107mvaddrawch - - -108mvwaddrawch - - -109110**man-end****************************************************************/111112int waddch(WINDOW *win, const chtype ch)113{114int x, y;115chtype text, attr;116bool xlat;117118PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",119win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));120121if (!win || !SP)122return ERR;123124x = win->_curx;125y = win->_cury;126127if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)128return ERR;129130xlat = !SP->raw_out && !(ch & A_ALTCHARSET);131text = ch & A_CHARTEXT;132attr = ch & A_ATTRIBUTES;133134if (xlat && (text < ' ' || text == 0x7f))135{136int x2;137138switch (text)139{140case '\t':141for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)142{143if (waddch(win, attr | ' ') == ERR)144return ERR;145146/* if tab to next line, exit the loop */147148if (!win->_curx)149break;150}151return OK;152153case '\n':154/* if lf -> crlf */155156if (!SP->raw_out)157x = 0;158159wclrtoeol(win);160161if (++y > win->_bmarg)162{163y--;164165if (wscrl(win, 1) == ERR)166return ERR;167}168169break;170171case '\b':172/* don't back over left margin */173174if (--x < 0)175case '\r':176x = 0;177178break;179180case 0x7f:181if (waddch(win, attr | '^') == ERR)182return ERR;183184return waddch(win, attr | '?');185186default:187/* handle control chars */188189if (waddch(win, attr | '^') == ERR)190return ERR;191192return waddch(win, ch + '@');193}194}195else196{197/* If the incoming character doesn't have its own attribute,198then use the current attributes for the window. If it has199attributes but not a color component, OR the attributes to200the current attributes for the window. If it has a color201component, use the attributes solely from the incoming202character. */203204if (!(attr & A_COLOR))205attr |= win->_attrs;206207/* wrs (4/10/93): Apply the same sort of logic for the window208background, in that it only takes precedence if other color209attributes are not there and that the background character210will only print if the printing character is blank. */211212if (!(attr & A_COLOR))213attr |= win->_bkgd & A_ATTRIBUTES;214else215attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);216217if (text == ' ')218text = win->_bkgd & A_CHARTEXT;219220/* Add the attribute back into the character. */221222text |= attr;223224/* Only change _firstch/_lastch if the character to be added is225different from the character/attribute that is already in226that position in the window. */227228if (win->_y[y][x] != text)229{230if (win->_firstch[y] == _NO_CHANGE)231win->_firstch[y] = win->_lastch[y] = x;232else233if (x < win->_firstch[y])234win->_firstch[y] = x;235else236if (x > win->_lastch[y])237win->_lastch[y] = x;238239win->_y[y][x] = text;240}241242if (++x >= win->_maxx)243{244/* wrap around test */245246x = 0;247248if (++y > win->_bmarg)249{250y--;251252if (wscrl(win, 1) == ERR)253{254PDC_sync(win);255return ERR;256}257}258}259}260261win->_curx = x;262win->_cury = y;263264if (win->_immed)265wrefresh(win);266if (win->_sync)267wsyncup(win);268269return OK;270}271272int addch(const chtype ch)273{274PDC_LOG(("addch() - called: ch=%x\n", ch));275276return waddch(stdscr, ch);277}278279int mvaddch(int y, int x, const chtype ch)280{281PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch));282283if (move(y,x) == ERR)284return ERR;285286return waddch(stdscr, ch);287}288289int mvwaddch(WINDOW *win, int y, int x, const chtype ch)290{291PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch));292293if (wmove(win, y, x) == ERR)294return ERR;295296return waddch(win, ch);297}298299int echochar(const chtype ch)300{301PDC_LOG(("echochar() - called: ch=%x\n", ch));302303return wechochar(stdscr, ch);304}305306int wechochar(WINDOW *win, const chtype ch)307{308PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch));309310if (waddch(win, ch) == ERR)311return ERR;312313return wrefresh(win);314}315316int waddrawch(WINDOW *win, chtype ch)317{318PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",319win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));320321if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)322ch |= A_ALTCHARSET;323324return waddch(win, ch);325}326327int addrawch(chtype ch)328{329PDC_LOG(("addrawch() - called: ch=%x\n", ch));330331return waddrawch(stdscr, ch);332}333334int mvaddrawch(int y, int x, chtype ch)335{336PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch));337338if (move(y, x) == ERR)339return ERR;340341return waddrawch(stdscr, ch);342}343344int mvwaddrawch(WINDOW *win, int y, int x, chtype ch)345{346PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n",347win, y, x, ch));348349if (wmove(win, y, x) == ERR)350return ERR;351352return waddrawch(win, ch);353}354355#ifdef PDC_WIDE356int wadd_wch(WINDOW *win, const cchar_t *wch)357{358PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch));359360return wch ? waddch(win, *wch) : ERR;361}362363int add_wch(const cchar_t *wch)364{365PDC_LOG(("add_wch() - called: wch=%x\n", *wch));366367return wadd_wch(stdscr, wch);368}369370int mvadd_wch(int y, int x, const cchar_t *wch)371{372PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch));373374if (move(y,x) == ERR)375return ERR;376377return wadd_wch(stdscr, wch);378}379380int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch)381{382PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n",383win, y, x, *wch));384385if (wmove(win, y, x) == ERR)386return ERR;387388return wadd_wch(win, wch);389}390391int echo_wchar(const cchar_t *wch)392{393PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch));394395return wecho_wchar(stdscr, wch);396}397398int wecho_wchar(WINDOW *win, const cchar_t *wch)399{400PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch));401402if (!wch || (wadd_wch(win, wch) == ERR))403return ERR;404405return wrefresh(win);406}407#endif408409410