2 * This file is part of the libpayload project.
4 * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
5 * Copyright (C) 2008 Ulf Jordan <jordan@chalmers.se>
6 * Copyright (C) 2008-2009 coresystems GmbH
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * This is a tiny implementation of the (n)curses library intended to be
34 * used in embedded/firmware/BIOS code where no libc or operating system
35 * environment is available and code size is very important.
38 * - Small object code.
40 * - Doesn't require a libc (no glibc/uclibc/dietlibc/klibc/newlib).
41 * - Works without any other external libraries or header files.
42 * - Works without an underlying operating system.
43 * - Doesn't use files, signals, syscalls, ttys, library calls, etc.
44 * - Doesn't do any dynamic memory allocation (no malloc() and friends).
45 * - All data structures are statically allocated.
46 * - Supports standard VGA console (80x25) and serial port console.
47 * - This includes character output and keyboard input over serial.
48 * - Supports beep() through a minimal PC speaker driver.
51 * - Only implements a small subset of the (n)curses functions.
52 * - Only implements very few sanity checks (for smaller code).
53 * - Thus: Don't do obviously stupid things in your code.
54 * - Doesn't implement the 'form', 'panel', and 'menu' extensions.
55 * - Only implements C bindings (no C++, Ada95, or others).
56 * - Doesn't include wide character support.
61 #undef _XOPEN_SOURCE_EXTENDED
62 #define _XOPEN_SOURCE_EXTENDED 1
66 /* Statically allocate all structures (no malloc())! */
67 static WINDOW window_list[MAX_WINDOWS];
68 static int window_count = 1;
71 static struct ldat ldat_list[MAX_WINDOWS][SCREEN_Y];
72 static int ldat_count = 0;
74 /* One item bigger than SCREEN_X to reserve space for a NUL byte. */
75 static NCURSES_CH_T linebuf_list[SCREEN_Y * MAX_WINDOWS][SCREEN_X + 1];
76 static int linebuf_count = 0;
79 int COLORS; /* Currently unused? */
80 int COLOR_PAIRS = 255;
93 /* See terminfo(5). */
94 chtype fallback_acs_map[128] =
96 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
97 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
98 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
99 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
100 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
101 ' ', ' ', ' ', '>', '<', '^', 'v', ' ',
102 '#', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
103 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
104 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
105 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
106 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
107 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
108 '+', ':', ' ', ' ', ' ', ' ', '\\', '#',
109 '#', '#', '+', '+', '+', '+', '+', '~',
110 '-', '-', '-', '_', '+', '+', '+', '+',
111 '|', '<', '>', '*', '!', 'f', 'o', ' ',
114 #ifdef CONFIG_SERIAL_CONSOLE
115 #ifdef CONFIG_SERIAL_ACS_FALLBACK
116 chtype serial_acs_map[128];
118 /* See acsc of vt100. */
119 chtype serial_acs_map[128] =
121 0, 0, 0, 0, 0, 0, 0, 0,
122 0, 0, 0, 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0,
124 0, 0, 0, 0, 0, 0, 0, 0,
125 0, 0, 0, 0, 0, 0, 0, 0,
126 0, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0,
128 0, 0, 0, 0, 0, 0, 0, 0,
129 0, 0, 0, 0, 0, 0, 0, 0,
130 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0,
133 '`', 'a', 0, 0, 0, 0, 'f', 'g',
134 0, 0, 'j', 'k', 'l', 'm', 'n', 'o',
135 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
136 'x', 'y', 'z', '{', '|', '}', '~', 0,
141 #ifdef CONFIG_VIDEO_CONSOLE
142 /* See acsc of linux. */
143 chtype console_acs_map[128] =
145 0, 0, 0, 0, 0, 0, 0, 0,
146 0, 0, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, 0, 0, 0, 0, 0,
148 0, 0, 0, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0,
150 0, 0, 0, '\020', '\021', '\030', '\031', 0,
151 '\333', 0, 0, 0, 0, 0, 0, 0,
152 0, 0, 0, 0, 0, 0, 0, 0,
153 0, 0, 0, 0, 0, 0, 0, 0,
154 0, 0, 0, 0, 0, 0, 0, 0,
155 0, 0, 0, 0, 0, 0, 0, 0,
156 0, 0, 0, 0, 0, 0, 0, 0,
157 '\004', '\261', 0, 0, 0, 0, '\370', '\361',
158 '\260', '\316', '\331', '\277', '\332', '\300', '\305', '~',
159 '\304', '\304', '\304', '_', '\303', '\264', '\301', '\302',
160 '\263', '\363', '\362', '\343', '\330', '\234', '\376', 0,
164 // FIXME: Ugly (and insecure!) hack!
165 char sprintf_tmp[1024];
168 int curses_flags = (F_ENABLE_CONSOLE | F_ENABLE_SERIAL);
170 /* Return bit mask for clearing color pair number if given ch has color */
171 #define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0))
173 /* Compute a rendition of the given char correct for the current context. */
174 static inline NCURSES_CH_T render_char(WINDOW *win, NCURSES_CH_T ch)
180 /* Make render_char() visible while still allowing us to inline it below. */
181 NCURSES_CH_T _nc_render(WINDOW *win, NCURSES_CH_T ch)
183 return render_char(win, ch);
187 * Implementations of most functions marked 'implemented' in include/curses.h:
190 // int baudrate(void) {}
193 /* TODO: Flash the screen if beeping fails? */
194 speaker_tone(1760, 500); /* 1760 == note A6 */
197 // bool can_change_color(void) {}
198 int cbreak(void) { /* TODO */ return 0; }
199 /* D */ int clearok(WINDOW *win, bool flag) { win->_clear = flag; return OK; }
200 // int color_content(short color, short *r, short *g, short *b) {}
203 #ifdef CONFIG_SERIAL_CONSOLE
204 if (curses_flags & F_ENABLE_SERIAL) {
205 serial_cursor_enable(on);
208 #ifdef CONFIG_VIDEO_CONSOLE
209 if (curses_flags & F_ENABLE_CONSOLE) {
210 video_console_cursor_enable(on);
216 // int def_prog_mode(void) {}
217 // int def_shell_mode(void) {}
218 // int delay_output(int) {}
219 // void delscreen(SCREEN *) {}
220 int delwin(WINDOW *win)
222 /* TODO: Don't try to delete stdscr. */
223 /* TODO: Don't delete parent windows before subwindows. */
225 // if (win->_flags & _SUBWIN)
226 // touchwin(win->_parent);
227 // else if (curscr != 0)
230 // return _nc_freewin(win);
233 WINDOW *derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
240 /* Make sure window fits inside the original one. */
241 if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0
245 if (begy + num_lines > orig->_maxy + 1
246 || begx + num_columns > orig->_maxx + 1)
250 num_lines = orig->_maxy + 1 - begy;
252 if (num_columns == 0)
253 num_columns = orig->_maxx + 1 - begx;
255 if (orig->_flags & _ISPAD)
259 if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
260 orig->_begx + begx, flags)) == 0)
265 WINDOW_ATTRS(win) = WINDOW_ATTRS(orig);
266 win->_nc_bkgd = orig->_nc_bkgd;
268 for (i = 0; i < num_lines; i++)
269 win->_line[i].text = &orig->_line[begy++].text[begx];
278 int doupdate(void) { /* TODO */ return(0); }
279 // WINDOW * dupwin (WINDOW *) {}
280 /* D */ int echo(void) { SP->_echo = TRUE; return OK; }
288 // _nc_screen_wrap();
289 // _nc_mvcur_wrap(); /* wrap up cursor addressing */
290 // return reset_shell_mode();
293 // char erasechar (void) {}
294 // void filter (void) {}
295 // int flash(void) {}
296 int flushinp(void) { /* TODO */ return 0; }
297 // WINDOW *getwin (FILE *) {}
298 bool has_colors (void) { return(TRUE); }
299 // bool has_ic (void) {}
300 // bool has_il (void) {}
301 // void idcok (WINDOW *, bool) {}
302 // int idlok (WINDOW *, bool) {}
303 void immedok(WINDOW *win, bool flag) { win->_immed = flag; }
304 /** Note: Must _not_ be called twice! */
305 WINDOW *initscr(void)
309 // newterm(name, stdout, stdin);
312 for (i = 0; i < 128; i++)
313 acs_map[i] = (chtype) i | A_ALTCHARSET;
314 #ifdef CONFIG_SERIAL_CONSOLE
315 if (curses_flags & F_ENABLE_SERIAL) {
319 #ifdef CONFIG_VIDEO_CONSOLE
320 if (curses_flags & F_ENABLE_CONSOLE) {
321 /* Clear the screen and kill the cursor */
323 video_console_clear();
324 video_console_cursor_enable(0);
330 stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0);
331 // TODO: curscr, newscr?
337 // int intrflush (WINDOW *,bool) {}
338 /* D */ bool isendwin(void) { return ((SP == NULL) ? FALSE : SP->_endwin); }
339 // bool is_linetouched (WINDOW *,int) {}
340 // bool is_wintouched (WINDOW *) {}
341 // NCURSES_CONST char * keyname (int) {}
342 int keypad (WINDOW *win, bool flag) { /* TODO */ return 0; }
343 // char killchar (void) {}
344 /* D */ int leaveok(WINDOW *win, bool flag) { win->_leaveok = flag; return OK; }
345 // char *longname (void) {}
346 // int meta (WINDOW *,bool) {}
347 // int mvcur (int,int,int,int) {}
348 // int mvderwin (WINDOW *, int, int) {}
349 int mvprintw(int y, int x, const char *fmt, ...)
354 if (move(y, x) == ERR)
358 code = vwprintw(stdscr, fmt, argp);
363 // int mvscanw (int,int, NCURSES_CONST char *,...) {}
364 // int mvwin (WINDOW *,int,int) {}
365 int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
370 if (wmove(win, y, x) == ERR)
374 code = vwprintw(win, fmt, argp);
379 // int mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) {}
380 // int napms (int) {}
381 // WINDOW *newpad (int,int) {}
382 // SCREEN *newterm (NCURSES_CONST char *,FILE *,FILE *) {}
383 WINDOW *newwin(int num_lines, int num_columns, int begy, int begx)
387 /* Use next statically allocated window. */
388 // TODO: Error handling.
390 WINDOW *win = &window_list[window_count++];
392 // bool is_pad = (flags & _ISPAD);
398 win->_maxy = num_lines - 1;
399 win->_maxx = num_columns - 1;
402 // win->_yoffset = SP->_topstolen;
404 win->_line = ldat_list[ldat_count++];
406 /* FIXME: Is this right? Should the window attributes be normal? */
407 win->_color = PAIR_NUMBER(0);
408 win->_attrs = A_NORMAL;
410 for (i = 0; i < num_lines; i++)
412 (NCURSES_CH_T *)&linebuf_list[linebuf_count++];
416 /* D */ int nl(void) { SP->_nl = TRUE; return OK; }
417 /* D */ int noecho(void) { SP->_echo = FALSE; return OK; }
418 /* D */ int nonl(void) { SP->_nl = FALSE; return OK; }
419 // void noqiflush (void) {}
420 // int noraw (void) {}
421 /* D */ int notimeout (WINDOW *win, bool f) { win->_notimeout = f; return OK; }
422 // int overlay (const WINDOW*,WINDOW *) {}
423 // int overwrite (const WINDOW*,WINDOW *) {}
424 // int pair_content (short,short*,short*) {}
425 // int pechochar (WINDOW *, const chtype) {}
426 // int pnoutrefresh (WINDOW*,int,int,int,int,int,int) {}
427 // int prefresh (WINDOW *,int,int,int,int,int,int) {}
428 int printw(const char *fmt, ...)
434 code = vwprintw(stdscr, fmt, argp);
439 // int putwin (WINDOW *, FILE *) {}
440 // void qiflush (void) {}
442 // int resetty (void) {}
443 // int reset_prog_mode (void) {}
444 // int reset_shell_mode (void) {}
445 // int ripoffline (int, int (*)(WINDOW *, int)) {}
446 // int savetty (void) {}
447 // int scanw (NCURSES_CONST char *,...) {}
448 // int scr_dump (const char *) {}
449 // int scr_init (const char *) {}
450 /* D */ int scrollok(WINDOW *win, bool flag) { win->_scroll = flag; return OK; }
451 // int scr_restore (const char *) {}
452 // int scr_set (const char *) {}
453 // SCREEN *set_term (SCREEN *) {}
454 // int slk_attroff (const chtype) {}
455 // int slk_attron (const chtype) {}
456 // int slk_attrset (const chtype) {}
457 // attr_t slk_attr (void) {}
458 // int slk_attr_set (const attr_t,short,void*) {}
459 // int slk_clear (void) {}
460 // int slk_color (short) {}
461 // int slk_init (int) {}
462 /* D */ char *slk_label(int n)
465 // if (SP == NULL || SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
467 return SP->_slk->ent[n - 1].ent_text;
469 // int slk_noutrefresh (void) {}
470 // int slk_refresh (void) {}
471 // int slk_restore (void) {}
472 // int slk_set (int,const char *,int) {}
473 // int slk_touch (void) {}
475 // WINDOW *subpad (WINDOW *, int, int, int, int) {}
476 WINDOW *subwin(WINDOW *w, int l, int c, int y, int x)
478 return derwin(w, l, c, y - w->_begy, x - w->_begx);
480 // int syncok (WINDOW *, bool) {}
481 // chtype termattrs (void) {}
482 // char *termname (void) {}
483 // int typeahead (int) {}
484 int ungetch(int ch) { /* TODO */ return ERR; }
485 // void use_env (bool) {}
486 // int vidattr (chtype) {}
487 // int vidputs (chtype, int (*)(int)) {}
488 int vwprintw(WINDOW *win, const char *fmt, va_list argp)
490 vsprintf((char *)&sprintf_tmp, fmt, argp);
492 /* TODO: Error handling? */
493 return waddstr(win, (char *)&sprintf_tmp);
495 // int vwscanw (WINDOW *, NCURSES_CONST char *,va_list) {}
496 int waddch(WINDOW *win, const chtype ch)
500 // SetChar2(wch, ch);
502 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
503 win->_line[win->_cury].firstchar > win->_curx)
504 win->_line[win->_cury].firstchar = win->_curx;
506 win->_line[win->_cury].text[win->_curx].chars[0] =
507 ((ch) & (chtype)A_CHARTEXT);
509 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
510 win->_line[win->_cury].text[win->_curx].attr |=
511 ((ch) & (chtype)A_ATTRIBUTES);
513 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
514 win->_line[win->_cury].lastchar < win->_curx)
515 win->_line[win->_cury].lastchar = win->_curx;
517 win->_curx++; // FIXME
519 // if (win && (waddch_nosync(win, wch) != ERR)) {
520 // _nc_synchook(win);
526 // int waddchnstr (WINDOW *,const chtype *,int) {}
527 int waddnstr(WINDOW *win, const char *astr, int n)
530 const char *str = astr;
538 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
539 win->_line[win->_cury].firstchar > win->_curx)
540 win->_line[win->_cury].firstchar = win->_curx;
542 while ((n-- > 0) && (*str != '\0')) {
543 // while (*str != '\0') {
544 win->_line[win->_cury].text[win->_curx].chars[0] = *str++;
545 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win)
547 win->_curx++; // FIXME
550 // SetChar(ch, UChar(*str++), A_NORMAL);
551 // if (_nc_waddch_nosync(win, ch) == ERR) {
557 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
558 win->_line[win->_cury].lastchar < win->_curx)
559 win->_line[win->_cury].lastchar = win->_curx;
563 int wattr_on(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
566 win->_color = PAIR_NUMBER(at);
567 // toggle_attr_on(WINDOW_ATTRS(win), at);
570 int wattr_off(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
574 // toggle_attr_off(WINDOW_ATTRS(win), at);
577 // int wbkgd (WINDOW *, chtype) {}
578 void wbkgdset(WINDOW *win, chtype ch) { /* TODO */ }
580 int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
581 chtype tl, chtype tr, chtype bl, chtype br)
585 for(y = 0; y <= win->_maxy; y++) {
588 mvwaddch(win, y, 0, tl);
590 for(x = 1; x < win->_maxx; x++)
591 mvwaddch(win, y, x, ts);
593 mvwaddch(win, y, win->_maxx, tr);
595 else if (y == win->_maxy) {
596 mvwaddch(win, y, 0, bl);
598 for(x = 1; x < win->_maxx; x++)
599 mvwaddch(win, y, x, bs);
601 mvwaddch(win, y, win->_maxx, br);
604 mvwaddch(win, y, 0, ls);
605 mvwaddch(win, y, win->_maxx, rs);
612 // int wchgat (WINDOW *, int, attr_t, short, const void *) {}
613 /* D */ int wclear(WINDOW *win)
615 if (werase(win) == ERR)
620 // int wclrtobot (WINDOW *) {}
621 int wclrtoeol(WINDOW *win) { /* TODO */ return ERR; }
622 int wcolor_set(WINDOW *win, short color_pair_number, void *opts)
624 if (!opts && (color_pair_number >= 0)
625 && (color_pair_number < COLOR_PAIRS)) {
626 SET_WINDOW_PAIR(win, color_pair_number);
627 if_EXT_COLORS(win->_color = color_pair_number);
632 // void wcursyncup (WINDOW *) {}
633 // int wdelch (WINDOW *) {}
634 // int wechochar (WINDOW *, const chtype) {}
635 int werase(WINDOW *win)
638 for (y = 0; y <= win->_maxy; y++) {
639 for (x = 0; x <= win->_maxx; x++) {
640 win->_line[y].text[x].chars[0] = ' ';
641 win->_line[y].text[x].attr = WINDOW_ATTRS(win);
643 // Should we check instead?
644 win->_line[y].firstchar = 0;
645 win->_line[y].lastchar = win->_maxx;
649 // int wgetnstr (WINDOW *,char *,int) {}
650 int whline(WINDOW *win, chtype ch, int n)
652 NCURSES_SIZE_T start, end;
653 struct ldat *line = &(win->_line[win->_cury]);
658 if (end > win->_maxx)
661 CHANGED_RANGE(line, start, end);
665 //// SetChar2(wch, ACS_HLINE);
667 //// SetChar2(wch, ch);
669 wch.chars[0] = ((ch) & (chtype)A_CHARTEXT);
670 wch.attr = ((ch) & (chtype)A_ATTRIBUTES);
671 wch = _nc_render(win, wch);
673 while (end >= start) {
674 line->text[end] = wch;
678 //// _nc_synchook(win);
682 /* D */ chtype winch(WINDOW *win)
685 // return (CharOf(win->_line[win->_cury].text[win->_curx]) |
686 // AttrOf(win->_line[win->_cury].text[win->_curx]));
689 // int winchnstr (WINDOW *, chtype *, int) {}
690 // int winnstr (WINDOW *, char *, int) {}
691 // int winsch (WINDOW *, chtype) {}
692 // int winsdelln (WINDOW *,int) {}
693 // int winsnstr (WINDOW *, const char *,int) {}
694 /* D */ int wmove(WINDOW *win, int y, int x)
696 if (!LEGALYX(win, y, x))
698 win->_curx = (NCURSES_SIZE_T) x;
699 win->_cury = (NCURSES_SIZE_T) y;
700 win->_flags &= ~_WRAPPED;
701 win->_flags |= _HASMOVED;
705 #define SWAP_RED_BLUE(c) \
706 (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
707 int wnoutrefresh(WINDOW *win)
709 #ifdef CONFIG_SERIAL_CONSOLE
711 int serial_is_bold = 0;
712 int serial_is_reverse = 0;
713 int serial_is_altcharset = 0;
714 int serial_cur_pair = 0;
722 #ifdef CONFIG_SERIAL_CONSOLE
724 serial_end_altcharset();
727 for (y = 0; y <= win->_maxy; y++) {
729 if (win->_line[y].firstchar == _NOCHANGE)
732 /* Position the serial cursor */
734 #ifdef CONFIG_SERIAL_CONSOLE
735 if (curses_flags & F_ENABLE_SERIAL)
736 serial_set_cursor(win->_begy + y, win->_begx +
737 win->_line[y].firstchar);
740 for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
741 attr_t attr = win->_line[y].text[x].attr;
743 #ifdef CONFIG_SERIAL_CONSOLE
744 if (curses_flags & F_ENABLE_SERIAL) {
745 ch = win->_line[y].text[x].chars[0];
748 if (!serial_is_bold) {
753 if (serial_is_bold) {
756 /* work around serial.c
759 serial_is_reverse = 0;
764 if (attr & A_REVERSE) {
765 if (!serial_is_reverse) {
766 serial_start_reverse();
767 serial_is_reverse = 1;
770 if (serial_is_reverse) {
771 serial_end_reverse();
772 serial_is_reverse = 0;
773 /* work around serial.c
782 if (attr & A_ALTCHARSET) {
783 if (serial_acs_map[ch & 0x7f]) {
784 ch = serial_acs_map[ch & 0x7f];
787 ch = fallback_acs_map[ch & 0x7f];
789 if (need_altcharset && !serial_is_altcharset) {
790 serial_start_altcharset();
791 serial_is_altcharset = 1;
793 if (!need_altcharset && serial_is_altcharset) {
794 serial_end_altcharset();
795 serial_is_altcharset = 0;
798 if (serial_cur_pair != PAIR_NUMBER(attr)) {
799 pair_content(PAIR_NUMBER(attr),
801 serial_set_color(fg, bg);
802 serial_cur_pair = PAIR_NUMBER(attr);
809 #ifdef CONFIG_VIDEO_CONSOLE
811 ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
813 c = SWAP_RED_BLUE(c);
815 if (curses_flags & F_ENABLE_CONSOLE) {
816 ch = win->_line[y].text[x].chars[0];
818 /* Handle some of the attributes. */
823 if (attr & A_REVERSE) {
824 unsigned char tmp = (c >> 8) & 0xf;
825 c = (c >> 4) & 0xf00;
828 if (attr & A_ALTCHARSET) {
829 if (console_acs_map[ch & 0x7f])
830 ch = console_acs_map[ch & 0x7f];
832 ch = fallback_acs_map[ch & 0x7f];
836 * FIXME: Somewhere along the line, the
837 * character value is getting sign-extented.
838 * For now grab just the 8 bit character,
839 * but this will break wide characters!
841 c |= (chtype) (ch & 0xff);
842 video_console_putc(win->_begy + y, win->_begx + x, c);
846 win->_line[y].firstchar = _NOCHANGE;
847 win->_line[y].lastchar = _NOCHANGE;
850 #ifdef CONFIG_SERIAL_CONSOLE
851 if (curses_flags & F_ENABLE_SERIAL)
852 serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
855 #ifdef CONFIG_VIDEO_CONSOLE
856 if (curses_flags & F_ENABLE_CONSOLE)
857 video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
862 int wprintw(WINDOW *win, const char *fmt, ...)
868 code = vwprintw(win, fmt, argp);
874 int wredrawln (WINDOW *win, int beg_line, int num_lines)
878 for (i = beg_line; i < beg_line + num_lines; i++) {
879 win->_line[i].firstchar = 0;
880 win->_line[i].lastchar = win->_maxx;
886 int wrefresh(WINDOW *win)
889 return wnoutrefresh(win);
895 curscr->_clear = TRUE;
896 // code = doupdate();
897 } else if ((code = wnoutrefresh(win)) == OK) {
899 newscr->_clear = TRUE;
900 // code = doupdate();
902 * Reset the clearok() flag in case it was set for the special
903 * case in hardscroll.c (if we don't reset it here, we'll get 2
904 * refreshes because the flag is copied from stdscr to newscr).
905 * Resetting the flag shouldn't do any harm, anyway.
912 // int wscanw (WINDOW *, NCURSES_CONST char *,...) {}
913 int wscrl(WINDOW *win, int n)
923 for (y = 0; y <= (win->_maxy - n); y++) {
924 win->_line[y].firstchar = win->_line[y + n].firstchar;
925 win->_line[y].lastchar = win->_line[y + n].lastchar;
926 for (x = 0; x <= win->_maxx; x++) {
927 if ((win->_line[y].text[x].chars[0] != win->_line[y + n].text[x].chars[0]) ||
928 (win->_line[y].text[x].attr != win->_line[y + n].text[x].attr)) {
929 if (win->_line[y].firstchar == _NOCHANGE)
930 win->_line[y].firstchar = x;
932 win->_line[y].lastchar = x;
934 win->_line[y].text[x].chars[0] = win->_line[y + n].text[x].chars[0];
935 win->_line[y].text[x].attr = win->_line[y + n].text[x].attr;
940 for (y = (win->_maxy+1 - n); y <= win->_maxy; y++) {
941 for (x = 0; x <= win->_maxx; x++) {
942 if ((win->_line[y].text[x].chars[0] != ' ') ||
943 (win->_line[y].text[x].attr != A_NORMAL)) {
944 if (win->_line[y].firstchar == _NOCHANGE)
945 win->_line[y].firstchar = x;
947 win->_line[y].lastchar = x;
949 win->_line[y].text[x].chars[0] = ' ';
950 win->_line[y].text[x].attr = A_NORMAL;
955 // _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd);
956 // _nc_synchook(win);
960 int wsetscrreg(WINDOW *win, int top, int bottom)
962 if (top >= 0 && top <= win->_maxy && bottom >= 0 &&
963 bottom <= win->_maxy && bottom > top) {
964 win->_regtop = (NCURSES_SIZE_T) top;
965 win->_regbottom = (NCURSES_SIZE_T) bottom;
970 // void wsyncdown (WINDOW *) {}
971 // void wsyncup (WINDOW *) {}
972 /* D */ void wtimeout(WINDOW *win, int delay) { win->_delay = delay; }
973 /* D */ int wtouchln(WINDOW *win, int y, int n, int changed)
977 // if ((n < 0) || (y < 0) || (y > win->_maxy))
980 for (i = y; i < y + n; i++) {
983 win->_line[i].firstchar = changed ? 0 : _NOCHANGE;
984 win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE;
988 // int wvline (WINDOW *,chtype,int) {}
989 // int tigetflag (NCURSES_CONST char *) {}
990 // int tigetnum (NCURSES_CONST char *) {}
991 // char *tigetstr (NCURSES_CONST char *) {}
992 // int putp (const char *) {}
993 // #if NCURSES_TPARM_VARARGS
994 // char *tparm (NCURSES_CONST char *, ...) {}
996 // char *tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long) {}
997 // char *tparm_varargs (NCURSES_CONST char *, ...) {}