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 #ifdef CONFIG_SPEAKER
195 speaker_tone(1760, 500); /* 1760 == note A6 */
199 // bool can_change_color(void) {}
200 int cbreak(void) { /* TODO */ return 0; }
201 /* D */ int clearok(WINDOW *win, bool flag) { win->_clear = flag; return OK; }
202 // int color_content(short color, short *r, short *g, short *b) {}
205 #ifdef CONFIG_SERIAL_CONSOLE
206 if (curses_flags & F_ENABLE_SERIAL) {
207 serial_cursor_enable(on);
210 #ifdef CONFIG_VIDEO_CONSOLE
211 if (curses_flags & F_ENABLE_CONSOLE) {
212 video_console_cursor_enable(on);
218 // int def_prog_mode(void) {}
219 // int def_shell_mode(void) {}
220 // int delay_output(int) {}
221 // void delscreen(SCREEN *) {}
222 int delwin(WINDOW *win)
224 /* TODO: Don't try to delete stdscr. */
225 /* TODO: Don't delete parent windows before subwindows. */
227 // if (win->_flags & _SUBWIN)
228 // touchwin(win->_parent);
229 // else if (curscr != 0)
232 // return _nc_freewin(win);
235 WINDOW *derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
242 /* Make sure window fits inside the original one. */
243 if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0
247 if (begy + num_lines > orig->_maxy + 1
248 || begx + num_columns > orig->_maxx + 1)
252 num_lines = orig->_maxy + 1 - begy;
254 if (num_columns == 0)
255 num_columns = orig->_maxx + 1 - begx;
257 if (orig->_flags & _ISPAD)
261 if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
262 orig->_begx + begx, flags)) == 0)
267 WINDOW_ATTRS(win) = WINDOW_ATTRS(orig);
268 win->_nc_bkgd = orig->_nc_bkgd;
270 for (i = 0; i < num_lines; i++)
271 win->_line[i].text = &orig->_line[begy++].text[begx];
280 int doupdate(void) { /* TODO */ return(0); }
281 // WINDOW * dupwin (WINDOW *) {}
282 /* D */ int echo(void) { SP->_echo = TRUE; return OK; }
289 #ifdef NCURSES_MOUSE_VERSION
292 // _nc_screen_wrap();
293 // _nc_mvcur_wrap(); /* wrap up cursor addressing */
294 // return reset_shell_mode();
297 // char erasechar (void) {}
298 // void filter (void) {}
299 // int flash(void) {}
300 int flushinp(void) { /* TODO */ return 0; }
301 // WINDOW *getwin (FILE *) {}
302 bool has_colors (void) { return(TRUE); }
303 // bool has_ic (void) {}
304 // bool has_il (void) {}
305 // void idcok (WINDOW *, bool) {}
306 // int idlok (WINDOW *, bool) {}
307 void immedok(WINDOW *win, bool flag) { win->_immed = flag; }
308 /** Note: Must _not_ be called twice! */
309 WINDOW *initscr(void)
313 // newterm(name, stdout, stdin);
316 for (i = 0; i < 128; i++)
317 acs_map[i] = (chtype) i | A_ALTCHARSET;
318 #ifdef CONFIG_SERIAL_CONSOLE
319 if (curses_flags & F_ENABLE_SERIAL) {
323 #ifdef CONFIG_VIDEO_CONSOLE
324 if (curses_flags & F_ENABLE_CONSOLE) {
325 /* Clear the screen and kill the cursor */
327 video_console_clear();
328 video_console_cursor_enable(0);
334 stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0);
335 // TODO: curscr, newscr?
341 // int intrflush (WINDOW *,bool) {}
342 /* D */ bool isendwin(void) { return ((SP == NULL) ? FALSE : SP->_endwin); }
343 // bool is_linetouched (WINDOW *,int) {}
344 // bool is_wintouched (WINDOW *) {}
345 // NCURSES_CONST char * keyname (int) {}
346 int keypad (WINDOW *win, bool flag) { /* TODO */ return 0; }
347 // char killchar (void) {}
348 /* D */ int leaveok(WINDOW *win, bool flag) { win->_leaveok = flag; return OK; }
349 // char *longname (void) {}
350 // int meta (WINDOW *,bool) {}
351 // int mvcur (int,int,int,int) {}
352 // int mvderwin (WINDOW *, int, int) {}
353 int mvprintw(int y, int x, const char *fmt, ...)
358 if (move(y, x) == ERR)
362 code = vwprintw(stdscr, fmt, argp);
367 // int mvscanw (int,int, NCURSES_CONST char *,...) {}
368 // int mvwin (WINDOW *,int,int) {}
369 int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
374 if (wmove(win, y, x) == ERR)
378 code = vwprintw(win, fmt, argp);
383 // int mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) {}
384 // int napms (int) {}
385 // WINDOW *newpad (int,int) {}
386 // SCREEN *newterm (NCURSES_CONST char *,FILE *,FILE *) {}
387 WINDOW *newwin(int num_lines, int num_columns, int begy, int begx)
391 /* Use next statically allocated window. */
392 // TODO: Error handling.
394 WINDOW *win = &window_list[window_count++];
396 // bool is_pad = (flags & _ISPAD);
402 win->_maxy = num_lines - 1;
403 win->_maxx = num_columns - 1;
406 // win->_yoffset = SP->_topstolen;
408 win->_line = ldat_list[ldat_count++];
410 /* FIXME: Is this right? Should the window attributes be normal? */
411 win->_color = PAIR_NUMBER(0);
412 win->_attrs = A_NORMAL;
414 for (i = 0; i < num_lines; i++)
416 (NCURSES_CH_T *)&linebuf_list[linebuf_count++];
420 /* D */ int nl(void) { SP->_nl = TRUE; return OK; }
421 /* D */ int noecho(void) { SP->_echo = FALSE; return OK; }
422 /* D */ int nonl(void) { SP->_nl = FALSE; return OK; }
423 // void noqiflush (void) {}
424 // int noraw (void) {}
425 /* D */ int notimeout (WINDOW *win, bool f) { win->_notimeout = f; return OK; }
426 // int overlay (const WINDOW*,WINDOW *) {}
427 // int overwrite (const WINDOW*,WINDOW *) {}
428 // int pair_content (short,short*,short*) {}
429 // int pechochar (WINDOW *, const chtype) {}
430 // int pnoutrefresh (WINDOW*,int,int,int,int,int,int) {}
431 // int prefresh (WINDOW *,int,int,int,int,int,int) {}
432 int printw(const char *fmt, ...)
438 code = vwprintw(stdscr, fmt, argp);
443 // int putwin (WINDOW *, FILE *) {}
444 // void qiflush (void) {}
446 // int resetty (void) {}
447 // int reset_prog_mode (void) {}
448 // int reset_shell_mode (void) {}
449 // int ripoffline (int, int (*)(WINDOW *, int)) {}
450 // int savetty (void) {}
451 // int scanw (NCURSES_CONST char *,...) {}
452 // int scr_dump (const char *) {}
453 // int scr_init (const char *) {}
454 /* D */ int scrollok(WINDOW *win, bool flag) { win->_scroll = flag; return OK; }
455 // int scr_restore (const char *) {}
456 // int scr_set (const char *) {}
457 // SCREEN *set_term (SCREEN *) {}
458 // int slk_attroff (const chtype) {}
459 // int slk_attron (const chtype) {}
460 // int slk_attrset (const chtype) {}
461 // attr_t slk_attr (void) {}
462 // int slk_attr_set (const attr_t,short,void*) {}
463 // int slk_clear (void) {}
464 // int slk_color (short) {}
465 // int slk_init (int) {}
466 /* D */ char *slk_label(int n)
469 // if (SP == NULL || SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
471 return SP->_slk->ent[n - 1].ent_text;
473 // int slk_noutrefresh (void) {}
474 // int slk_refresh (void) {}
475 // int slk_restore (void) {}
476 // int slk_set (int,const char *,int) {}
477 // int slk_touch (void) {}
479 // WINDOW *subpad (WINDOW *, int, int, int, int) {}
480 WINDOW *subwin(WINDOW *w, int l, int c, int y, int x)
482 return derwin(w, l, c, y - w->_begy, x - w->_begx);
484 // int syncok (WINDOW *, bool) {}
485 // chtype termattrs (void) {}
486 // char *termname (void) {}
487 // int typeahead (int) {}
488 int ungetch(int ch) { /* TODO */ return ERR; }
489 // void use_env (bool) {}
490 // int vidattr (chtype) {}
491 // int vidputs (chtype, int (*)(int)) {}
492 int vwprintw(WINDOW *win, const char *fmt, va_list argp)
494 vsprintf((char *)&sprintf_tmp, fmt, argp);
496 /* TODO: Error handling? */
497 return waddstr(win, (char *)&sprintf_tmp);
499 // int vwscanw (WINDOW *, NCURSES_CONST char *,va_list) {}
500 int waddch(WINDOW *win, const chtype ch)
504 // SetChar2(wch, ch);
506 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
507 win->_line[win->_cury].firstchar > win->_curx)
508 win->_line[win->_cury].firstchar = win->_curx;
510 win->_line[win->_cury].text[win->_curx].chars[0] =
511 ((ch) & (chtype)A_CHARTEXT);
513 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
514 win->_line[win->_cury].text[win->_curx].attr |=
515 ((ch) & (chtype)A_ATTRIBUTES);
517 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
518 win->_line[win->_cury].lastchar < win->_curx)
519 win->_line[win->_cury].lastchar = win->_curx;
521 win->_curx++; // FIXME
523 // if (win && (waddch_nosync(win, wch) != ERR)) {
524 // _nc_synchook(win);
530 // int waddchnstr (WINDOW *,const chtype *,int) {}
531 int waddnstr(WINDOW *win, const char *astr, int n)
534 const char *str = astr;
542 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
543 win->_line[win->_cury].firstchar > win->_curx)
544 win->_line[win->_cury].firstchar = win->_curx;
546 while ((n-- > 0) && (*str != '\0')) {
547 // while (*str != '\0') {
548 win->_line[win->_cury].text[win->_curx].chars[0] = *str++;
549 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win)
551 win->_curx++; // FIXME
554 // SetChar(ch, UChar(*str++), A_NORMAL);
555 // if (_nc_waddch_nosync(win, ch) == ERR) {
561 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
562 win->_line[win->_cury].lastchar < win->_curx)
563 win->_line[win->_cury].lastchar = win->_curx;
567 int wattr_on(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
570 win->_color = PAIR_NUMBER(at);
571 // toggle_attr_on(WINDOW_ATTRS(win), at);
574 int wattr_off(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
578 // toggle_attr_off(WINDOW_ATTRS(win), at);
581 // int wbkgd (WINDOW *, chtype) {}
582 void wbkgdset(WINDOW *win, chtype ch) { /* TODO */ }
584 int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
585 chtype tl, chtype tr, chtype bl, chtype br)
589 if (ls == 0) ls = ACS_VLINE;
590 if (rs == 0) rs = ACS_VLINE;
591 if (ts == 0) ts = ACS_HLINE;
592 if (bs == 0) bs = ACS_HLINE;
593 if (tl == 0) tl = ACS_ULCORNER;
594 if (tr == 0) tr = ACS_URCORNER;
595 if (bl == 0) bl = ACS_LLCORNER;
596 if (br == 0) br = ACS_LRCORNER;
598 for(y = 0; y <= win->_maxy; y++) {
601 mvwaddch(win, y, 0, tl);
603 for(x = 1; x < win->_maxx; x++)
604 mvwaddch(win, y, x, ts);
606 mvwaddch(win, y, win->_maxx, tr);
608 else if (y == win->_maxy) {
609 mvwaddch(win, y, 0, bl);
611 for(x = 1; x < win->_maxx; x++)
612 mvwaddch(win, y, x, bs);
614 mvwaddch(win, y, win->_maxx, br);
617 mvwaddch(win, y, 0, ls);
618 mvwaddch(win, y, win->_maxx, rs);
625 // int wchgat (WINDOW *, int, attr_t, short, const void *) {}
626 /* D */ int wclear(WINDOW *win)
628 if (werase(win) == ERR)
633 // int wclrtobot (WINDOW *) {}
634 int wclrtoeol(WINDOW *win) { /* TODO */ return ERR; }
635 int wcolor_set(WINDOW *win, short color_pair_number, void *opts)
637 if (!opts && (color_pair_number >= 0)
638 && (color_pair_number < COLOR_PAIRS)) {
639 SET_WINDOW_PAIR(win, color_pair_number);
640 if_EXT_COLORS(win->_color = color_pair_number);
645 // void wcursyncup (WINDOW *) {}
646 // int wdelch (WINDOW *) {}
647 // int wechochar (WINDOW *, const chtype) {}
648 int werase(WINDOW *win)
651 for (y = 0; y <= win->_maxy; y++) {
652 for (x = 0; x <= win->_maxx; x++) {
653 win->_line[y].text[x].chars[0] = ' ';
654 win->_line[y].text[x].attr = WINDOW_ATTRS(win);
656 // Should we check instead?
657 win->_line[y].firstchar = 0;
658 win->_line[y].lastchar = win->_maxx;
662 // int wgetnstr (WINDOW *,char *,int) {}
663 int whline(WINDOW *win, chtype ch, int n)
665 NCURSES_SIZE_T start, end;
666 struct ldat *line = &(win->_line[win->_cury]);
671 if (end > win->_maxx)
674 CHANGED_RANGE(line, start, end);
678 //// SetChar2(wch, ACS_HLINE);
680 //// SetChar2(wch, ch);
682 wch.chars[0] = ((ch) & (chtype)A_CHARTEXT);
683 wch.attr = ((ch) & (chtype)A_ATTRIBUTES);
684 wch = _nc_render(win, wch);
686 while (end >= start) {
687 line->text[end] = wch;
691 //// _nc_synchook(win);
695 /* D */ chtype winch(WINDOW *win)
698 // return (CharOf(win->_line[win->_cury].text[win->_curx]) |
699 // AttrOf(win->_line[win->_cury].text[win->_curx]));
702 // int winchnstr (WINDOW *, chtype *, int) {}
703 // int winnstr (WINDOW *, char *, int) {}
704 // int winsch (WINDOW *, chtype) {}
705 // int winsdelln (WINDOW *,int) {}
706 // int winsnstr (WINDOW *, const char *,int) {}
707 /* D */ int wmove(WINDOW *win, int y, int x)
709 if (!LEGALYX(win, y, x))
711 win->_curx = (NCURSES_SIZE_T) x;
712 win->_cury = (NCURSES_SIZE_T) y;
713 win->_flags &= ~_WRAPPED;
714 win->_flags |= _HASMOVED;
718 #define SWAP_RED_BLUE(c) \
719 (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
720 int wnoutrefresh(WINDOW *win)
722 #ifdef CONFIG_SERIAL_CONSOLE
724 int serial_is_bold = 0;
725 int serial_is_reverse = 0;
726 int serial_is_altcharset = 0;
727 int serial_cur_pair = 0;
735 #ifdef CONFIG_SERIAL_CONSOLE
737 serial_end_altcharset();
740 for (y = 0; y <= win->_maxy; y++) {
742 if (win->_line[y].firstchar == _NOCHANGE)
745 /* Position the serial cursor */
747 #ifdef CONFIG_SERIAL_CONSOLE
748 if (curses_flags & F_ENABLE_SERIAL)
749 serial_set_cursor(win->_begy + y, win->_begx +
750 win->_line[y].firstchar);
753 for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
754 attr_t attr = win->_line[y].text[x].attr;
756 #ifdef CONFIG_SERIAL_CONSOLE
757 if (curses_flags & F_ENABLE_SERIAL) {
758 ch = win->_line[y].text[x].chars[0];
761 if (!serial_is_bold) {
766 if (serial_is_bold) {
769 /* work around serial.c
772 serial_is_reverse = 0;
777 if (attr & A_REVERSE) {
778 if (!serial_is_reverse) {
779 serial_start_reverse();
780 serial_is_reverse = 1;
783 if (serial_is_reverse) {
784 serial_end_reverse();
785 serial_is_reverse = 0;
786 /* work around serial.c
795 if (attr & A_ALTCHARSET) {
796 if (serial_acs_map[ch & 0x7f]) {
797 ch = serial_acs_map[ch & 0x7f];
800 ch = fallback_acs_map[ch & 0x7f];
802 if (need_altcharset && !serial_is_altcharset) {
803 serial_start_altcharset();
804 serial_is_altcharset = 1;
806 if (!need_altcharset && serial_is_altcharset) {
807 serial_end_altcharset();
808 serial_is_altcharset = 0;
811 if (serial_cur_pair != PAIR_NUMBER(attr)) {
812 pair_content(PAIR_NUMBER(attr),
814 serial_set_color(fg, bg);
815 serial_cur_pair = PAIR_NUMBER(attr);
822 #ifdef CONFIG_VIDEO_CONSOLE
824 ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
826 c = SWAP_RED_BLUE(c);
828 if (curses_flags & F_ENABLE_CONSOLE) {
829 ch = win->_line[y].text[x].chars[0];
831 /* Handle some of the attributes. */
836 if (attr & A_REVERSE) {
837 unsigned char tmp = (c >> 8) & 0xf;
838 c = (c >> 4) & 0xf00;
841 if (attr & A_ALTCHARSET) {
842 if (console_acs_map[ch & 0x7f])
843 ch = console_acs_map[ch & 0x7f];
845 ch = fallback_acs_map[ch & 0x7f];
849 * FIXME: Somewhere along the line, the
850 * character value is getting sign-extented.
851 * For now grab just the 8 bit character,
852 * but this will break wide characters!
854 c |= (chtype) (ch & 0xff);
855 video_console_putc(win->_begy + y, win->_begx + x, c);
859 win->_line[y].firstchar = _NOCHANGE;
860 win->_line[y].lastchar = _NOCHANGE;
863 #ifdef CONFIG_SERIAL_CONSOLE
864 if (curses_flags & F_ENABLE_SERIAL)
865 serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
868 #ifdef CONFIG_VIDEO_CONSOLE
869 if (curses_flags & F_ENABLE_CONSOLE)
870 video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
875 int wprintw(WINDOW *win, const char *fmt, ...)
881 code = vwprintw(win, fmt, argp);
887 int wredrawln (WINDOW *win, int beg_line, int num_lines)
891 for (i = beg_line; i < beg_line + num_lines; i++) {
892 win->_line[i].firstchar = 0;
893 win->_line[i].lastchar = win->_maxx;
899 int wrefresh(WINDOW *win)
902 return wnoutrefresh(win);
908 curscr->_clear = TRUE;
909 // code = doupdate();
910 } else if ((code = wnoutrefresh(win)) == OK) {
912 newscr->_clear = TRUE;
913 // code = doupdate();
915 * Reset the clearok() flag in case it was set for the special
916 * case in hardscroll.c (if we don't reset it here, we'll get 2
917 * refreshes because the flag is copied from stdscr to newscr).
918 * Resetting the flag shouldn't do any harm, anyway.
925 // int wscanw (WINDOW *, NCURSES_CONST char *,...) {}
926 int wscrl(WINDOW *win, int n)
936 for (y = 0; y <= (win->_maxy - n); y++) {
937 win->_line[y].firstchar = win->_line[y + n].firstchar;
938 win->_line[y].lastchar = win->_line[y + n].lastchar;
939 for (x = 0; x <= win->_maxx; x++) {
940 if ((win->_line[y].text[x].chars[0] != win->_line[y + n].text[x].chars[0]) ||
941 (win->_line[y].text[x].attr != win->_line[y + n].text[x].attr)) {
942 if (win->_line[y].firstchar == _NOCHANGE)
943 win->_line[y].firstchar = x;
945 win->_line[y].lastchar = x;
947 win->_line[y].text[x].chars[0] = win->_line[y + n].text[x].chars[0];
948 win->_line[y].text[x].attr = win->_line[y + n].text[x].attr;
953 for (y = (win->_maxy+1 - n); y <= win->_maxy; y++) {
954 for (x = 0; x <= win->_maxx; x++) {
955 if ((win->_line[y].text[x].chars[0] != ' ') ||
956 (win->_line[y].text[x].attr != A_NORMAL)) {
957 if (win->_line[y].firstchar == _NOCHANGE)
958 win->_line[y].firstchar = x;
960 win->_line[y].lastchar = x;
962 win->_line[y].text[x].chars[0] = ' ';
963 win->_line[y].text[x].attr = A_NORMAL;
968 // _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd);
969 // _nc_synchook(win);
973 int wsetscrreg(WINDOW *win, int top, int bottom)
975 if (top >= 0 && top <= win->_maxy && bottom >= 0 &&
976 bottom <= win->_maxy && bottom > top) {
977 win->_regtop = (NCURSES_SIZE_T) top;
978 win->_regbottom = (NCURSES_SIZE_T) bottom;
983 // void wsyncdown (WINDOW *) {}
984 // void wsyncup (WINDOW *) {}
985 /* D */ void wtimeout(WINDOW *win, int _delay) { win->_delay = _delay; }
986 /* D */ int wtouchln(WINDOW *win, int y, int n, int changed)
990 // if ((n < 0) || (y < 0) || (y > win->_maxy))
993 for (i = y; i < y + n; i++) {
996 win->_line[i].firstchar = changed ? 0 : _NOCHANGE;
997 win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE;
1001 // int wvline (WINDOW *,chtype,int) {}
1002 // int tigetflag (NCURSES_CONST char *) {}
1003 // int tigetnum (NCURSES_CONST char *) {}
1004 // char *tigetstr (NCURSES_CONST char *) {}
1005 // int putp (const char *) {}
1006 // #if NCURSES_TPARM_VARARGS
1007 // char *tparm (NCURSES_CONST char *, ...) {}
1009 // char *tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long) {}
1010 // char *tparm_varargs (NCURSES_CONST char *, ...) {}