586d1a71fa6ce5d80a60f627d83e266581c4e542
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / pdcurses / addch.c
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: addch.c,v 1.54 2008/07/13 16:08:17 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9   Name:                                                         addch
10
11   Synopsis:
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);
18
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);
23
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);
30
31   Description:
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.
38
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
41         wide version.
42
43         mvaddch() moves the cursor to the specified (y, x) position, and
44         adds ch to stdscr. mvadd_wch() is the wide version.
45
46         mvwaddch() moves the cursor to the specified position and adds 
47         ch to the specified window. mvwadd_wch() is the wide version.
48
49         echochar() adds ch to stdscr at the current cursor position and 
50         calls refresh(). echo_wchar() is the wide version.
51
52         wechochar() adds ch to the specified window and calls 
53         wrefresh(). wecho_wchar() is the wide version.
54
55         addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are
56         PDCurses-specific wrappers for addch() etc. that disable the 
57         translation of control characters.
58
59         The following applies to all these functions:
60
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 
65         will be returned.
66
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 
77         character.
78
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().
82
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.
89
90   Return Value:
91         All functions return OK on success and ERR on error.
92
93   Portability                                X/Open    BSD    SYS V
94         addch                                   Y       Y       Y
95         waddch                                  Y       Y       Y
96         mvaddch                                 Y       Y       Y
97         mvwaddch                                Y       Y       Y
98         echochar                                Y       -      3.0
99         wechochar                               Y       -      3.0
100         addrawch                                -       -       -
101         waddrawch                               -       -       -
102         mvaddrawch                              -       -       -
103         mvwaddrawch                             -       -       -
104         add_wch                                 Y
105         wadd_wch                                Y
106         mvadd_wch                               Y
107         mvwadd_wch                              Y
108         echo_wchar                              Y
109         wecho_wchar                             Y
110
111 **man-end****************************************************************/
112
113 int waddch(WINDOW *win, const chtype ch)
114 {
115     int x, y;
116     chtype text, attr;
117     bool xlat;
118
119     PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
120              win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
121
122     if (!win)
123         return ERR;
124
125     x = win->_curx;
126     y = win->_cury;
127
128     if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0)
129         return ERR;
130
131     xlat = !SP->raw_out && !(ch & A_ALTCHARSET);
132     text = ch & A_CHARTEXT;
133     attr = ch & A_ATTRIBUTES;
134
135     if (xlat && (text < ' ' || text == 0x7f))
136     {
137         int x2;
138
139         switch (text)
140         {
141         case '\t':
142             for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++)
143             {
144                 if (waddch(win, attr | ' ') == ERR)
145                     return ERR;
146
147                 /* if tab to next line, exit the loop */
148
149                 if (!win->_curx)
150                     break;
151             }
152             return OK;
153
154         case '\n':
155             /* if lf -> crlf */
156
157             if (!SP->raw_out)
158                 x = 0;
159
160             wclrtoeol(win);
161
162             if (++y > win->_bmarg)
163             {
164                 y--;
165
166                 if (wscrl(win, 1) == ERR)
167                     return ERR;
168             }
169
170             break;
171
172         case '\b':
173             /* don't back over left margin */
174
175             if (--x < 0)
176         case '\r':
177                 x = 0;
178
179             break;
180
181         case 0x7f:
182             if (waddch(win, attr | '^') == ERR)
183                 return ERR;
184
185             return waddch(win, attr | '?');
186
187         default:
188             /* handle control chars */
189
190             if (waddch(win, attr | '^') == ERR)
191                 return ERR;
192
193             return waddch(win, ch + '@');
194         }
195     }
196     else
197     {
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
203            character. */
204
205         if (!(attr & A_COLOR))
206             attr |= win->_attrs;
207
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. */
212
213         if (!(attr & A_COLOR))
214             attr |= win->_bkgd & A_ATTRIBUTES;
215         else
216             attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR);
217
218         if (text == ' ')
219             text = win->_bkgd & A_CHARTEXT;
220
221         /* Add the attribute back into the character. */
222
223         text |= attr;
224
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. */
228
229         if (win->_y[y][x] != text)
230         {
231             if (win->_firstch[y] == _NO_CHANGE)
232                 win->_firstch[y] = win->_lastch[y] = x;
233             else
234                 if (x < win->_firstch[y])
235                     win->_firstch[y] = x;
236                 else
237                     if (x > win->_lastch[y])
238                         win->_lastch[y] = x;
239
240             win->_y[y][x] = text;
241         }
242
243         if (++x >= win->_maxx)
244         {
245             /* wrap around test */
246
247             x = 0;
248
249             if (++y > win->_bmarg)
250             {
251                 y--;
252
253                 if (wscrl(win, 1) == ERR)
254                 {
255                     PDC_sync(win);
256                     return ERR;
257                 }
258             }
259         }
260     }
261
262     win->_curx = x;
263     win->_cury = y;
264
265     if (win->_immed)
266         wrefresh(win);
267     if (win->_sync)
268         wsyncup(win);
269
270     return OK;
271 }
272
273 int addch(const chtype ch)
274 {
275     PDC_LOG(("addch() - called: ch=%x\n", ch));
276
277     return waddch(stdscr, ch);
278 }
279
280 int mvaddch(int y, int x, const chtype ch)
281 {
282     PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch));
283
284     if (move(y,x) == ERR)
285         return ERR;
286
287     return waddch(stdscr, ch);
288 }
289
290 int mvwaddch(WINDOW *win, int y, int x, const chtype ch)
291 {
292     PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch));
293
294     if (wmove(win, y, x) == ERR)
295         return ERR;
296
297     return waddch(win, ch);
298 }
299
300 int echochar(const chtype ch)
301 {
302     PDC_LOG(("echochar() - called: ch=%x\n", ch));
303
304     return wechochar(stdscr, ch);
305 }
306
307 int wechochar(WINDOW *win, const chtype ch)
308 {
309     PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch));
310
311     if (waddch(win, ch) == ERR)
312         return ERR;
313
314     return wrefresh(win);
315 }
316
317 int waddrawch(WINDOW *win, chtype ch)
318 {
319     PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n",
320              win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES));
321
322     if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f)
323         ch |= A_ALTCHARSET;
324
325     return waddch(win, ch);
326 }
327
328 int addrawch(chtype ch)
329 {
330     PDC_LOG(("addrawch() - called: ch=%x\n", ch));
331
332     return waddrawch(stdscr, ch);
333 }
334
335 int mvaddrawch(int y, int x, chtype ch)
336 {
337     PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch));
338
339     if (move(y, x) == ERR)
340         return ERR;
341
342     return waddrawch(stdscr, ch);
343 }
344
345 int mvwaddrawch(WINDOW *win, int y, int x, chtype ch)
346 {
347     PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n",
348              win, y, x, ch));
349
350     if (wmove(win, y, x) == ERR)
351         return ERR;
352
353     return waddrawch(win, ch);
354 }
355
356 #ifdef PDC_WIDE
357 int wadd_wch(WINDOW *win, const cchar_t *wch)
358 {
359     PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch));
360
361     return wch ? waddch(win, *wch) : ERR;
362 }
363
364 int add_wch(const cchar_t *wch)
365 {
366     PDC_LOG(("add_wch() - called: wch=%x\n", *wch));
367
368     return wadd_wch(stdscr, wch);
369 }
370
371 int mvadd_wch(int y, int x, const cchar_t *wch)
372 {
373     PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch));
374
375     if (move(y,x) == ERR)
376         return ERR;
377
378     return wadd_wch(stdscr, wch);
379 }
380
381 int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch)
382 {
383     PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n",
384              win, y, x, *wch));
385
386     if (wmove(win, y, x) == ERR)
387         return ERR;
388
389     return wadd_wch(win, wch);
390 }
391
392 int echo_wchar(const cchar_t *wch)
393 {
394     PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch));
395
396     return wecho_wchar(stdscr, wch);
397 }
398
399 int wecho_wchar(WINDOW *win, const cchar_t *wch)
400 {
401     PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch));
402
403     if (!wch || (wadd_wch(win, wch) == ERR))
404         return ERR;
405
406     return wrefresh(win);
407 }
408 #endif