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 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? */
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_ACS_FALLBACK
115 chtype serial_acs_map[128];
117 /* See acsc of vt100. */
118 chtype serial_acs_map[128] =
120 0, 0, 0, 0, 0, 0, 0, 0,
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 '`', 'a', 0, 0, 0, 0, 'f', 'g',
133 0, 0, 'j', 'k', 'l', 'm', 'n', 'o',
134 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
135 'x', 'y', 'z', '{', '|', '}', '~', 0,
139 /* See acsc of linux. */
140 chtype console_acs_map[128] =
142 0, 0, 0, 0, 0, 0, 0, 0,
143 0, 0, 0, 0, 0, 0, 0, 0,
144 0, 0, 0, 0, 0, 0, 0, 0,
145 0, 0, 0, 0, 0, 0, 0, 0,
146 0, 0, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, '\020', '\021', '\030', '\031', 0,
148 '\333', 0, 0, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0,
150 0, 0, 0, 0, 0, 0, 0, 0,
151 0, 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 '\004', '\261', 0, 0, 0, 0, '\370', '\361',
155 '\260', '\316', '\331', '\277', '\332', '\300', '\305', '~',
156 '\304', '\304', '\304', '_', '\303', '\264', '\301', '\302',
157 '\263', '\363', '\362', '\343', '\330', '\234', '\376', 0,
160 // FIXME: Ugly (and insecure!) hack!
161 char sprintf_tmp[1024];
164 int curses_flags = (F_ENABLE_CONSOLE | F_ENABLE_SERIAL);
166 /* Return bit mask for clearing color pair number if given ch has color */
167 #define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0))
169 /* Compute a rendition of the given char correct for the current context. */
170 static inline NCURSES_CH_T render_char(WINDOW *win, NCURSES_CH_T ch)
176 /* Make render_char() visible while still allowing us to inline it below. */
177 NCURSES_CH_T _nc_render(WINDOW *win, NCURSES_CH_T ch)
179 return render_char(win, ch);
183 * Implementations of most functions marked 'implemented' in include/curses.h:
186 // int baudrate(void) {}
189 /* TODO: Flash the screen if beeping fails? */
190 speaker_tone(1760, 500); /* 1760 == note A6 */
193 // bool can_change_color(void) {}
194 int cbreak(void) { /* TODO */ return 0; }
195 /* D */ int clearok(WINDOW *win, bool flag) { win->_clear = flag; return OK; }
196 // int color_content(short color, short *r, short *g, short *b) {}
199 if (curses_flags & F_ENABLE_SERIAL) {
203 if (curses_flags & F_ENABLE_CONSOLE) {
204 video_console_cursor_enable(on);
209 // int def_prog_mode(void) {}
210 // int def_shell_mode(void) {}
211 // int delay_output(int) {}
212 // void delscreen(SCREEN *) {}
213 int delwin(WINDOW *win)
215 /* TODO: Don't try to delete stdscr. */
216 /* TODO: Don't delete parent windows before subwindows. */
218 // if (win->_flags & _SUBWIN)
219 // touchwin(win->_parent);
220 // else if (curscr != 0)
223 // return _nc_freewin(win);
226 WINDOW *derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
232 /* Make sure window fits inside the original one. */
233 if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0
237 if (begy + num_lines > orig->_maxy + 1
238 || begx + num_columns > orig->_maxx + 1)
242 num_lines = orig->_maxy + 1 - begy;
244 if (num_columns == 0)
245 num_columns = orig->_maxx + 1 - begx;
247 if (orig->_flags & _ISPAD)
251 //// if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
252 //// orig->_begx + begx, flags)) == 0)
257 WINDOW_ATTRS(win) = WINDOW_ATTRS(orig);
258 win->_nc_bkgd = orig->_nc_bkgd;
260 for (i = 0; i < num_lines; i++)
261 win->_line[i].text = &orig->_line[begy++].text[begx];
267 int doupdate(void) { /* TODO */ return(0); }
268 // WINDOW * dupwin (WINDOW *) {}
269 /* D */ int echo(void) { SP->_echo = TRUE; return OK; }
277 // _nc_screen_wrap();
278 // _nc_mvcur_wrap(); /* wrap up cursor addressing */
279 // return reset_shell_mode();
282 // char erasechar (void) {}
283 // void filter (void) {}
284 // int flash(void) {}
285 int flushinp(void) { /* TODO */ return 0; }
286 // WINDOW *getwin (FILE *) {}
287 bool has_colors (void) { /* TODO */ return(*(bool *)0); }
288 // bool has_ic (void) {}
289 // bool has_il (void) {}
290 // void idcok (WINDOW *, bool) {}
291 // int idlok (WINDOW *, bool) {}
292 void immedok(WINDOW *win, bool flag) { win->_immed = flag; }
293 /** Note: Must _not_ be called twice! */
294 WINDOW *initscr(void)
298 // newterm(name, stdout, stdin);
301 for (i = 0; i < 128; i++)
302 acs_map[i] = (chtype) i | A_ALTCHARSET;
304 if (curses_flags & F_ENABLE_SERIAL) {
308 if (curses_flags & F_ENABLE_CONSOLE) {
309 /* Clear the screen and kill the cursor */
311 video_console_clear();
312 video_console_cursor_enable(0);
317 stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0);
318 // TODO: curscr, newscr?
324 // int intrflush (WINDOW *,bool) {}
325 /* D */ bool isendwin(void) { return ((SP == NULL) ? FALSE : SP->_endwin); }
326 // bool is_linetouched (WINDOW *,int) {}
327 // bool is_wintouched (WINDOW *) {}
328 // NCURSES_CONST char * keyname (int) {}
329 int keypad (WINDOW *win, bool flag) { /* TODO */ return 0; }
330 // char killchar (void) {}
331 /* D */ int leaveok(WINDOW *win, bool flag) { win->_leaveok = flag; return OK; }
332 // char *longname (void) {}
333 // int meta (WINDOW *,bool) {}
334 // int mvcur (int,int,int,int) {}
335 // int mvderwin (WINDOW *, int, int) {}
336 int mvprintw(int y, int x, const char *fmt, ...)
341 if (move(y, x) == ERR)
345 code = vwprintw(stdscr, fmt, argp);
350 // int mvscanw (int,int, NCURSES_CONST char *,...) {}
351 // int mvwin (WINDOW *,int,int) {}
352 int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
357 if (wmove(win, y, x) == ERR)
361 code = vwprintw(win, fmt, argp);
366 // int mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) {}
367 // int napms (int) {}
368 // WINDOW *newpad (int,int) {}
369 // SCREEN *newterm (NCURSES_CONST char *,FILE *,FILE *) {}
370 WINDOW *newwin(int num_lines, int num_columns, int begy, int begx)
374 /* Use next statically allocated window. */
375 // TODO: Error handling.
377 WINDOW *win = &window_list[window_count++];
379 // bool is_pad = (flags & _ISPAD);
385 win->_maxy = num_lines - 1;
386 win->_maxx = num_columns - 1;
389 // win->_yoffset = SP->_topstolen;
391 win->_line = ldat_list[ldat_count++];
393 /* FIXME: Is this right? Should the window attributes be normal? */
394 win->_color = PAIR_NUMBER(0);
395 win->_attrs = A_NORMAL;
397 for (i = 0; i < num_lines; i++)
399 (NCURSES_CH_T *)&linebuf_list[linebuf_count++];
403 /* D */ int nl(void) { SP->_nl = TRUE; return OK; }
404 /* D */ int noecho(void) { SP->_echo = FALSE; return OK; }
405 /* D */ int nonl(void) { SP->_nl = FALSE; return OK; }
406 // void noqiflush (void) {}
407 // int noraw (void) {}
408 /* D */ int notimeout (WINDOW *win, bool f) { win->_notimeout = f; return OK; }
409 // int overlay (const WINDOW*,WINDOW *) {}
410 // int overwrite (const WINDOW*,WINDOW *) {}
411 // int pair_content (short,short*,short*) {}
412 // int pechochar (WINDOW *, const chtype) {}
413 // int pnoutrefresh (WINDOW*,int,int,int,int,int,int) {}
414 // int prefresh (WINDOW *,int,int,int,int,int,int) {}
415 int printw(const char *fmt, ...)
421 code = vwprintw(stdscr, fmt, argp);
426 // int putwin (WINDOW *, FILE *) {}
427 // void qiflush (void) {}
429 // int resetty (void) {}
430 // int reset_prog_mode (void) {}
431 // int reset_shell_mode (void) {}
432 // int ripoffline (int, int (*)(WINDOW *, int)) {}
433 // int savetty (void) {}
434 // int scanw (NCURSES_CONST char *,...) {}
435 // int scr_dump (const char *) {}
436 // int scr_init (const char *) {}
437 /* D */ int scrollok(WINDOW *win, bool flag) { win->_scroll = flag; return OK; }
438 // int scr_restore (const char *) {}
439 // int scr_set (const char *) {}
440 // SCREEN *set_term (SCREEN *) {}
441 // int slk_attroff (const chtype) {}
442 // int slk_attron (const chtype) {}
443 // int slk_attrset (const chtype) {}
444 // attr_t slk_attr (void) {}
445 // int slk_attr_set (const attr_t,short,void*) {}
446 // int slk_clear (void) {}
447 // int slk_color (short) {}
448 // int slk_init (int) {}
449 /* D */ char *slk_label(int n)
452 // if (SP == NULL || SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
454 return SP->_slk->ent[n - 1].ent_text;
456 // int slk_noutrefresh (void) {}
457 // int slk_refresh (void) {}
458 // int slk_restore (void) {}
459 // int slk_set (int,const char *,int) {}
460 // int slk_touch (void) {}
462 // WINDOW *subpad (WINDOW *, int, int, int, int) {}
463 WINDOW *subwin(WINDOW *w, int l, int c, int y, int x)
465 return derwin(w, l, c, y - w->_begy, x - w->_begx);
467 // int syncok (WINDOW *, bool) {}
468 // chtype termattrs (void) {}
469 // char *termname (void) {}
470 // int typeahead (int) {}
471 int ungetch(int ch) { /* TODO */ return ERR; }
472 // void use_env (bool) {}
473 // int vidattr (chtype) {}
474 // int vidputs (chtype, int (*)(int)) {}
475 int vwprintw(WINDOW *win, const char *fmt, va_list argp)
477 vsprintf((char *)&sprintf_tmp, fmt, argp);
479 /* TODO: Error handling? */
480 return waddstr(win, (char *)&sprintf_tmp);
482 // int vwscanw (WINDOW *, NCURSES_CONST char *,va_list) {}
483 int waddch(WINDOW *win, const chtype ch)
487 // SetChar2(wch, ch);
489 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
490 win->_line[win->_cury].firstchar > win->_curx)
491 win->_line[win->_cury].firstchar = win->_curx;
493 win->_line[win->_cury].text[win->_curx].chars[0] =
494 ((ch) & (chtype)A_CHARTEXT);
496 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
497 win->_line[win->_cury].text[win->_curx].attr |=
498 ((ch) & (chtype)A_ATTRIBUTES);
500 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
501 win->_line[win->_cury].lastchar < win->_curx)
502 win->_line[win->_cury].lastchar = win->_curx;
504 win->_curx++; // FIXME
506 // if (win && (waddch_nosync(win, wch) != ERR)) {
507 // _nc_synchook(win);
513 // int waddchnstr (WINDOW *,const chtype *,int) {}
514 int waddnstr(WINDOW *win, const char *astr, int n)
517 const char *str = astr;
525 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
526 win->_line[win->_cury].firstchar > win->_curx)
527 win->_line[win->_cury].firstchar = win->_curx;
529 while ((n-- > 0) && (*str != '\0')) {
530 // while (*str != '\0') {
531 win->_line[win->_cury].text[win->_curx].chars[0] = *str++;
532 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win)
534 win->_curx++; // FIXME
537 // SetChar(ch, UChar(*str++), A_NORMAL);
538 // if (_nc_waddch_nosync(win, ch) == ERR) {
544 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
545 win->_line[win->_cury].lastchar < win->_curx)
546 win->_line[win->_cury].lastchar = win->_curx;
550 int wattr_on(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
553 win->_color = PAIR_NUMBER(at);
554 // toggle_attr_on(WINDOW_ATTRS(win), at);
557 int wattr_off(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
561 // toggle_attr_off(WINDOW_ATTRS(win), at);
564 // int wbkgd (WINDOW *, chtype) {}
565 void wbkgdset(WINDOW *win, chtype ch) { /* TODO */ }
567 int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
568 chtype tl, chtype tr, chtype bl, chtype br)
572 for(y = 0; y <= win->_maxy; y++) {
575 mvwaddch(win, y, 0, tl);
577 for(x = 1; x < win->_maxx; x++)
578 mvwaddch(win, y, x, ts);
580 mvwaddch(win, y, win->_maxx, tr);
582 else if (y == win->_maxy) {
583 mvwaddch(win, y, 0, bl);
585 for(x = 1; x < win->_maxx; x++)
586 mvwaddch(win, y, x, bs);
588 mvwaddch(win, y, win->_maxx, br);
591 mvwaddch(win, y, 0, ls);
592 mvwaddch(win, y, win->_maxx, rs);
599 // int wchgat (WINDOW *, int, attr_t, short, const void *) {}
600 /* D */ int wclear(WINDOW *win)
602 if (werase(win) == ERR)
607 // int wclrtobot (WINDOW *) {}
608 int wclrtoeol(WINDOW *win) { /* TODO */ return(*(int *)0); }
609 int wcolor_set(WINDOW *win, short color_pair_number, void *opts)
611 if (!opts && (color_pair_number >= 0)
612 && (color_pair_number < COLOR_PAIRS)) {
613 SET_WINDOW_PAIR(win, color_pair_number);
614 if_EXT_COLORS(win->_color = color_pair_number);
619 // void wcursyncup (WINDOW *) {}
620 // int wdelch (WINDOW *) {}
621 // int wechochar (WINDOW *, const chtype) {}
622 int werase(WINDOW *win)
625 for (y = 0; y <= win->_maxy; y++) {
626 for (x = 0; x <= win->_maxx; x++) {
627 win->_line[y].text[x].chars[0] = ' ';
628 win->_line[y].text[x].attr = WINDOW_ATTRS(win);
630 // Should we check instead?
631 win->_line[y].firstchar = 0;
632 win->_line[y].lastchar = win->_maxx;
636 // int wgetnstr (WINDOW *,char *,int) {}
637 int whline(WINDOW *win, chtype ch, int n)
639 NCURSES_SIZE_T start, end;
640 struct ldat *line = &(win->_line[win->_cury]);
645 if (end > win->_maxx)
648 CHANGED_RANGE(line, start, end);
652 //// SetChar2(wch, ACS_HLINE);
654 //// SetChar2(wch, ch);
656 wch.chars[0] = ((ch) & (chtype)A_CHARTEXT);
657 wch.attr = ((ch) & (chtype)A_ATTRIBUTES);
658 wch = _nc_render(win, wch);
660 while (end >= start) {
661 line->text[end] = wch;
665 //// _nc_synchook(win);
669 /* D */ chtype winch(WINDOW *win)
672 // return (CharOf(win->_line[win->_cury].text[win->_curx]) |
673 // AttrOf(win->_line[win->_cury].text[win->_curx]));
676 // int winchnstr (WINDOW *, chtype *, int) {}
677 // int winnstr (WINDOW *, char *, int) {}
678 // int winsch (WINDOW *, chtype) {}
679 // int winsdelln (WINDOW *,int) {}
680 // int winsnstr (WINDOW *, const char *,int) {}
681 /* D */ int wmove(WINDOW *win, int y, int x)
683 if (!LEGALYX(win, y, x))
685 win->_curx = (NCURSES_SIZE_T) x;
686 win->_cury = (NCURSES_SIZE_T) y;
687 win->_flags &= ~_WRAPPED;
688 win->_flags |= _HASMOVED;
692 #define SWAP_RED_BLUE(c) \
693 (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
694 int wnoutrefresh(WINDOW *win)
697 int serial_is_bold = 0;
698 int serial_is_altcharset = 0;
699 int serial_cur_pair = 0;
707 serial_end_altcharset();
709 for (y = 0; y <= win->_maxy; y++) {
711 if (win->_line[y].firstchar == _NOCHANGE)
714 /* Position the serial cursor */
716 if (curses_flags & F_ENABLE_SERIAL)
717 serial_set_cursor(win->_begy + y, win->_begx +
718 win->_line[y].firstchar);
720 for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
721 attr_t attr = win->_line[y].text[x].attr;
724 ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
726 if (curses_flags & F_ENABLE_SERIAL) {
727 ch = win->_line[y].text[x].chars[0];
730 if (!serial_is_bold) {
736 if (serial_is_bold) {
744 if (attr & A_ALTCHARSET) {
745 if (serial_acs_map[ch & 0x7f]) {
746 ch = serial_acs_map[ch & 0x7f];
749 ch = fallback_acs_map[ch & 0x7f];
751 if (need_altcharset && !serial_is_altcharset) {
752 serial_start_altcharset();
753 serial_is_altcharset = 1;
755 if (!need_altcharset && serial_is_altcharset) {
756 serial_end_altcharset();
757 serial_is_altcharset = 0;
760 if (serial_cur_pair != PAIR_NUMBER(attr)) {
761 pair_content(PAIR_NUMBER(attr),
763 serial_set_color(fg, bg);
764 serial_cur_pair = PAIR_NUMBER(attr);
771 c = SWAP_RED_BLUE(c);
773 if (curses_flags & F_ENABLE_CONSOLE) {
774 ch = win->_line[y].text[x].chars[0];
776 /* Handle some of the attributes. */
781 if (attr & A_REVERSE) {
782 unsigned char tmp = (c >> 8) & 0xf;
783 c = (c >> 4) & 0xf00;
786 if (attr & A_ALTCHARSET) {
787 if (console_acs_map[ch & 0x7f])
788 ch = console_acs_map[ch & 0x7f];
790 ch = fallback_acs_map[ch & 0x7f];
794 * FIXME: Somewhere along the line, the
795 * character value is getting sign-extented.
796 * For now grab just the 8 bit character,
797 * but this will break wide characters!
799 c |= (chtype) (ch & 0xff);
800 video_console_putc(win->_begy + y, win->_begx + x, c);
803 win->_line[y].firstchar = _NOCHANGE;
804 win->_line[y].lastchar = _NOCHANGE;
807 if (curses_flags & F_ENABLE_SERIAL)
808 serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
810 if (curses_flags & F_ENABLE_CONSOLE)
811 video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
815 int wprintw(WINDOW *win, const char *fmt, ...)
821 code = vwprintw(win, fmt, argp);
826 // int wredrawln (WINDOW *,int,int) {}
827 int wrefresh(WINDOW *win)
830 return wnoutrefresh(win);
836 curscr->_clear = TRUE;
837 // code = doupdate();
838 } else if ((code = wnoutrefresh(win)) == OK) {
840 newscr->_clear = TRUE;
841 // code = doupdate();
843 * Reset the clearok() flag in case it was set for the special
844 * case in hardscroll.c (if we don't reset it here, we'll get 2
845 * refreshes because the flag is copied from stdscr to newscr).
846 * Resetting the flag shouldn't do any harm, anyway.
853 // int wscanw (WINDOW *, NCURSES_CONST char *,...) {}
854 int wscrl(WINDOW *win, int n)
864 for (y = 0; y <= (win->_maxy - n); y++) {
865 win->_line[y].firstchar = win->_line[y + n].firstchar;
866 win->_line[y].lastchar = win->_line[y + n].lastchar;
867 for (x = 0; x <= win->_maxx; x++) {
868 if ((win->_line[y].text[x].chars[0] != win->_line[y + n].text[x].chars[0]) ||
869 (win->_line[y].text[x].attr != win->_line[y + n].text[x].attr)) {
870 if (win->_line[y].firstchar == _NOCHANGE)
871 win->_line[y].firstchar = x;
873 win->_line[y].lastchar = x;
875 win->_line[y].text[x].chars[0] = win->_line[y + n].text[x].chars[0];
876 win->_line[y].text[x].attr = win->_line[y + n].text[x].attr;
881 for (y = (win->_maxy+1 - n); y <= win->_maxy; y++) {
882 for (x = 0; x <= win->_maxx; x++) {
883 if ((win->_line[y].text[x].chars[0] != ' ') ||
884 (win->_line[y].text[x].attr != A_NORMAL)) {
885 if (win->_line[y].firstchar == _NOCHANGE)
886 win->_line[y].firstchar = x;
888 win->_line[y].lastchar = x;
890 win->_line[y].text[x].chars[0] = ' ';
891 win->_line[y].text[x].attr = A_NORMAL;
896 // _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd);
897 // _nc_synchook(win);
901 int wsetscrreg(WINDOW *win, int top, int bottom)
903 if (top >= 0 && top <= win->_maxy && bottom >= 0 &&
904 bottom <= win->_maxy && bottom > top) {
905 win->_regtop = (NCURSES_SIZE_T) top;
906 win->_regbottom = (NCURSES_SIZE_T) bottom;
911 // void wsyncdown (WINDOW *) {}
912 // void wsyncup (WINDOW *) {}
913 /* D */ void wtimeout(WINDOW *win, int delay) { win->_delay = delay; }
914 /* D */ int wtouchln(WINDOW *win, int y, int n, int changed)
918 // if ((n < 0) || (y < 0) || (y > win->_maxy))
921 for (i = y; i < y + n; i++) {
924 win->_line[i].firstchar = changed ? 0 : _NOCHANGE;
925 win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE;
929 // int wvline (WINDOW *,chtype,int) {}
930 // int tigetflag (NCURSES_CONST char *) {}
931 // int tigetnum (NCURSES_CONST char *) {}
932 // char *tigetstr (NCURSES_CONST char *) {}
933 // int putp (const char *) {}
934 // #if NCURSES_TPARM_VARARGS
935 // char *tparm (NCURSES_CONST char *, ...) {}
937 // char *tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long) {}
938 // char *tparm_varargs (NCURSES_CONST char *, ...) {}