1 /* Public Domain Curses */
5 RCSID("$Id: addch.c,v 1.54 2008/07/13 16:08:17 wmcbrine Exp $")
7 /*man-start**************************************************************
12 int addch(const chtype ch);
13 int waddch(WINDOW *win, const chtype ch);
14 int mvaddch(int y, int x, const chtype ch);
15 int mvwaddch(WINDOW *win, int y, int x, const chtype ch);
16 int echochar(const chtype ch);
17 int wechochar(WINDOW *win, const chtype ch);
19 int addrawch(chtype ch);
20 int waddrawch(WINDOW *win, chtype ch);
21 int mvaddrawch(int y, int x, chtype ch);
22 int mvwaddrawch(WINDOW *win, int y, int x, chtype ch);
24 int add_wch(const cchar_t *wch);
25 int wadd_wch(WINDOW *win, const cchar_t *wch);
26 int mvadd_wch(int y, int x, const cchar_t *wch);
27 int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch);
28 int echo_wchar(const cchar_t *wch);
29 int wecho_wchar(WINDOW *win, const cchar_t *wch);
32 addch() adds the chtype ch to the default window (stdscr) at the
33 current cursor position, and advances the cursor. Note that
34 chtypes can convey both text (a single character) and
35 attributes, including a color pair. add_wch() is the wide-
36 character version of this function, taking a pointer to a
37 cchar_t instead of a chtype.
39 waddch() is like addch(), but also lets you specify the window.
40 (This is in fact the core output routine.) wadd_wch() is the
43 mvaddch() moves the cursor to the specified (y, x) position, and
44 adds ch to stdscr. mvadd_wch() is the wide version.
46 mvwaddch() moves the cursor to the specified position and adds
47 ch to the specified window. mvwadd_wch() is the wide version.
49 echochar() adds ch to stdscr at the current cursor position and
50 calls refresh(). echo_wchar() is the wide version.
52 wechochar() adds ch to the specified window and calls
53 wrefresh(). wecho_wchar() is the wide version.
55 addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are
56 PDCurses-specific wrappers for addch() etc. that disable the
57 translation of control characters.
59 The following applies to all these functions:
61 If the cursor moves on to the right margin, an automatic newline
62 is performed. If scrollok is enabled, and a character is added
63 to the bottom right corner of the window, the scrolling region
64 will be scrolled up one line. If scrolling is not allowed, ERR
67 If ch is a tab, newline, or backspace, the cursor will be moved
68 appropriately within the window. If ch is a newline, the
69 clrtoeol routine is called before the cursor is moved to the
70 beginning of the next line. If newline mapping is off, the
71 cursor will be moved to the next line, but the x coordinate will
72 be unchanged. If ch is a tab the cursor is moved to the next
73 tab position within the window. If ch is another control
74 character, it will be drawn in the ^X notation. Calling the
75 inch() routine after adding a control character returns the
76 representation of the control character, not the control
79 Video attributes can be combined with a character by ORing them
80 into the parameter. Text, including attributes, can be copied
81 from one place to another by using inch() and addch().
83 Note that in PDCurses, for now, a cchar_t and a chtype are the
84 same. The text field is 16 bits wide, and is treated as Unicode
85 (UCS-2) when PDCurses is built with wide-character support
86 (define PDC_WIDE). So, in functions that take a chtype, like
87 addch(), both the wide and narrow versions will handle Unicode.
88 But for portability, you should use the wide functions.
91 All functions return OK on success and ERR on error.
93 Portability X/Open BSD SYS V
111 **man-end****************************************************************/
113 int waddch(WINDOW *win, const chtype ch)
119 PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
120 win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
128 if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
131 xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
132 text = ch & A_CHARTEXT;
133 attr = ch & A_ATTRIBUTES;
135 if (xlat && (text < ' ' || text == 0x7f))
142 for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
144 if (waddch(win, attr | ' ') == ERR)
147 /* if tab to next line, exit the loop */
162 if (++y > win->_bmarg)
166 if (wscrl(win, 1) == ERR)
173 /* don't back over left margin */
182 if (waddch(win, attr | '^') == ERR)
185 return waddch(win, attr | '?');
188 /* handle control chars */
190 if (waddch(win, attr | '^') == ERR)
193 return waddch(win, ch + '@');
198 /* If the incoming character doesn't have its own attribute,
199 then use the current attributes for the window. If it has
200 attributes but not a color component, OR the attributes to
201 the current attributes for the window. If it has a color
202 component, use the attributes solely from the incoming
205 if (!(attr & A_COLOR))
208 /* wrs (4/10/93): Apply the same sort of logic for the window
209 background, in that it only takes precedence if other color
210 attributes are not there and that the background character
211 will only print if the printing character is blank. */
213 if (!(attr & A_COLOR))
214 attr |= win->_bkgd & A_ATTRIBUTES;
216 attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
219 text = win->_bkgd & A_CHARTEXT;
221 /* Add the attribute back into the character. */
225 /* Only change _firstch/_lastch if the character to be added is
226 different from the character/attribute that is already in
227 that position in the window. */
229 if (win->_y[y][x] != text)
231 if (win->_firstch[y] == _NO_CHANGE)
232 win->_firstch[y] = win->_lastch[y] = x;
234 if (x < win->_firstch[y])
235 win->_firstch[y] = x;
237 if (x > win->_lastch[y])
240 win->_y[y][x] = text;
243 if (++x >= win->_maxx)
245 /* wrap around test */
249 if (++y > win->_bmarg)
253 if (wscrl(win, 1) == ERR)
273 int addch(const chtype ch)
275 PDC_LOG(("addch() - called: ch=%x\n", ch));
277 return waddch(stdscr, ch);
280 int mvaddch(int y, int x, const chtype ch)
282 PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch));
284 if (move(y,x) == ERR)
287 return waddch(stdscr, ch);
290 int mvwaddch(WINDOW *win, int y, int x, const chtype ch)
292 PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch));
294 if (wmove(win, y, x) == ERR)
297 return waddch(win, ch);
300 int echochar(const chtype ch)
302 PDC_LOG(("echochar() - called: ch=%x\n", ch));
304 return wechochar(stdscr, ch);
307 int wechochar(WINDOW *win, const chtype ch)
309 PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch));
311 if (waddch(win, ch) == ERR)
314 return wrefresh(win);
317 int waddrawch(WINDOW *win, chtype ch)
319 PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
320 win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
322 if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
325 return waddch(win, ch);
328 int addrawch(chtype ch)
330 PDC_LOG(("addrawch() - called: ch=%x\n", ch));
332 return waddrawch(stdscr, ch);
335 int mvaddrawch(int y, int x, chtype ch)
337 PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch));
339 if (move(y, x) == ERR)
342 return waddrawch(stdscr, ch);
345 int mvwaddrawch(WINDOW *win, int y, int x, chtype ch)
347 PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n",
350 if (wmove(win, y, x) == ERR)
353 return waddrawch(win, ch);
357 int wadd_wch(WINDOW *win, const cchar_t *wch)
359 PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch));
361 return wch ? waddch(win, *wch) : ERR;
364 int add_wch(const cchar_t *wch)
366 PDC_LOG(("add_wch() - called: wch=%x\n", *wch));
368 return wadd_wch(stdscr, wch);
371 int mvadd_wch(int y, int x, const cchar_t *wch)
373 PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch));
375 if (move(y,x) == ERR)
378 return wadd_wch(stdscr, wch);
381 int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch)
383 PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n",
386 if (wmove(win, y, x) == ERR)
389 return wadd_wch(win, wch);
392 int echo_wchar(const cchar_t *wch)
394 PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch));
396 return wecho_wchar(stdscr, wch);
399 int wecho_wchar(WINDOW *win, const cchar_t *wch)
401 PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch));
403 if (!wch || (wadd_wch(win, wch) == ERR))
406 return wrefresh(win);