mb/google/kahlee: Enable 2T mode for liara in DVT phase
[coreboot.git] / payloads / libpayload / curses / tinycurses.c
blob789accb475b2c2be258c46b7161f5c56c1a70939
1 /*
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
10 * are met:
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
29 * SUCH DAMAGE.
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.
37 * Design goals:
38 * - Small object code.
39 * - Self-contained.
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.
50 * Limitations:
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.
59 #include "local.h"
61 #undef _XOPEN_SOURCE_EXTENDED
62 #define _XOPEN_SOURCE_EXTENDED 1
64 #define MAX_WINDOWS 3
66 /* Statically allocate all structures (no malloc())! */
67 static WINDOW window_list[MAX_WINDOWS];
68 static int window_count = 0;
70 // struct ldat foo;
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;
78 /* Globals */
79 int COLORS; /* Currently unused? */
80 int COLOR_PAIRS = 255;
81 WINDOW *stdscr;
82 WINDOW *curscr;
83 WINDOW *newscr;
84 int LINES = 25;
85 int COLS = 80;
86 int TABSIZE;
87 int ESCDELAY;
88 // char ttytype[];
89 // cchar_t *_nc_wacs;
90 SCREEN *SP;
91 chtype acs_map[128];
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 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
115 #if IS_ENABLED(CONFIG_LP_SERIAL_ACS_FALLBACK)
116 chtype serial_acs_map[128];
117 #else
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,
138 #endif
139 #endif
141 #if IS_ENABLED(CONFIG_LP_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,
162 #endif
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)
176 /* TODO. */
177 return 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) {}
191 int beep(void)
193 /* TODO: Flash the screen if beeping fails? */
194 #if IS_ENABLED(CONFIG_LP_SPEAKER)
195 speaker_tone(1760, 500); /* 1760 == note A6 */
196 #endif
197 return OK;
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) {}
203 int curs_set(int on)
205 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
206 if (curses_flags & F_ENABLE_SERIAL) {
207 serial_cursor_enable(on);
209 #endif
210 #if IS_ENABLED(CONFIG_LP_VIDEO_CONSOLE)
211 if (curses_flags & F_ENABLE_CONSOLE) {
212 video_console_cursor_enable(on);
214 #endif
216 return OK;
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)
230 // touchwin(curscr);
232 // return _nc_freewin(win);
233 return OK;
235 WINDOW *derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
237 #if 0
238 WINDOW *win = NULL;
239 int i;
240 int flags = _SUBWIN;
242 /* Make sure window fits inside the original one. */
243 if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0
244 || num_columns < 0)
245 return NULL;
247 if (begy + num_lines > orig->_maxy + 1
248 || begx + num_columns > orig->_maxx + 1)
249 return NULL;
251 if (num_lines == 0)
252 num_lines = orig->_maxy + 1 - begy;
254 if (num_columns == 0)
255 num_columns = orig->_maxx + 1 - begx;
257 if (orig->_flags & _ISPAD)
258 flags |= _ISPAD;
260 // FIXME
261 if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
262 orig->_begx + begx, flags)) == 0)
263 return NULL;
265 win->_pary = begy;
266 win->_parx = begx;
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];
273 win->_parent = orig;
275 return win;
276 #else
277 return NULL;
278 #endif
280 int doupdate(void) { /* TODO */ return(0); }
281 // WINDOW * dupwin (WINDOW *) {}
282 /* D */ int echo(void) { SP->_echo = TRUE; return OK; }
283 int endwin(void)
285 if (!SP)
286 return ERR;
288 SP->_endwin = TRUE;
289 #ifdef NCURSES_MOUSE_VERSION
290 SP->_mouse_wrap(SP);
291 #endif
292 // _nc_screen_wrap();
293 // _nc_mvcur_wrap(); /* wrap up cursor addressing */
294 // return reset_shell_mode();
295 return OK; // FIXME
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)
311 int i;
313 // newterm(name, stdout, stdin);
314 // def_prog_mode();
316 for (i = 0; i < 128; i++)
317 acs_map[i] = (chtype) i | A_ALTCHARSET;
318 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
319 if (curses_flags & F_ENABLE_SERIAL) {
320 serial_clear();
322 #endif
323 #if IS_ENABLED(CONFIG_LP_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);
330 #endif
332 // Speaker init?
334 stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0);
335 // TODO: curscr, newscr?
337 werase(stdscr);
339 return stdscr;
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, ...)
355 va_list argp;
356 int code;
358 if (move(y, x) == ERR)
359 return ERR;
361 va_start(argp, fmt);
362 code = vwprintw(stdscr, fmt, argp);
363 va_end(argp);
365 return code;
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, ...)
371 va_list argp;
372 int code;
374 if (wmove(win, y, x) == ERR)
375 return ERR;
377 va_start(argp, fmt);
378 code = vwprintw(win, fmt, argp);
379 va_end(argp);
381 return code;
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)
389 WINDOW *win;
390 int i;
392 /* Use next statically allocated window. */
393 // TODO: Error handling. Yes. Please.
394 // TODO: WINDOWLIST?
396 if (window_count >= MAX_WINDOWS)
397 return NULL;
399 win = &window_list[window_count++];
401 // bool is_pad = (flags & _ISPAD);
403 // TODO: Checks.
405 win->_cury = 0;
406 win->_curx = 0;
407 win->_maxy = num_lines - 1;
408 win->_maxx = num_columns - 1;
409 win->_begy = begy;
410 win->_begx = begx;
411 // win->_yoffset = SP->_topstolen;
413 win->_line = ldat_list[ldat_count++];
415 /* FIXME: Is this right? Should the window attributes be normal? */
416 win->_color = PAIR_NUMBER(0);
417 win->_attrs = A_NORMAL;
419 for (i = 0; i < num_lines; i++)
420 win->_line[i].text =
421 (NCURSES_CH_T *)&linebuf_list[linebuf_count++];
423 return win;
425 /* D */ int nl(void) { SP->_nl = TRUE; return OK; }
426 /* D */ int noecho(void) { SP->_echo = FALSE; return OK; }
427 /* D */ int nonl(void) { SP->_nl = FALSE; return OK; }
428 // void noqiflush (void) {}
429 // int noraw (void) {}
430 /* D */ int notimeout (WINDOW *win, bool f) { win->_notimeout = f; return OK; }
431 // int overlay (const WINDOW*,WINDOW *) {}
432 // int overwrite (const WINDOW*,WINDOW *) {}
433 // int pair_content (short,short*,short*) {}
434 // int pechochar (WINDOW *, const chtype) {}
435 // int pnoutrefresh (WINDOW*,int,int,int,int,int,int) {}
436 // int prefresh (WINDOW *,int,int,int,int,int,int) {}
437 int printw(const char *fmt, ...)
439 va_list argp;
440 int code;
442 va_start(argp, fmt);
443 code = vwprintw(stdscr, fmt, argp);
444 va_end(argp);
446 return code;
448 // int putwin (WINDOW *, FILE *) {}
449 // void qiflush (void) {}
450 // int raw (void) {}
451 // int resetty (void) {}
452 // int reset_prog_mode (void) {}
453 // int reset_shell_mode (void) {}
454 // int ripoffline (int, int (*)(WINDOW *, int)) {}
455 // int savetty (void) {}
456 // int scanw (NCURSES_CONST char *,...) {}
457 // int scr_dump (const char *) {}
458 // int scr_init (const char *) {}
459 /* D */ int scrollok(WINDOW *win, bool flag) { win->_scroll = flag; return OK; }
460 // int scr_restore (const char *) {}
461 // int scr_set (const char *) {}
462 // SCREEN *set_term (SCREEN *) {}
463 // int slk_attroff (const chtype) {}
464 // int slk_attron (const chtype) {}
465 // int slk_attrset (const chtype) {}
466 // attr_t slk_attr (void) {}
467 // int slk_attr_set (const attr_t,short,void*) {}
468 // int slk_clear (void) {}
469 // int slk_color (short) {}
470 // int slk_init (int) {}
471 /* D */ char *slk_label(int n)
473 // TODO: Needed?
474 // if (SP == NULL || SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
475 // return NULL;
476 return SP->_slk->ent[n - 1].ent_text;
478 // int slk_noutrefresh (void) {}
479 // int slk_refresh (void) {}
480 // int slk_restore (void) {}
481 // int slk_set (int,const char *,int) {}
482 // int slk_touch (void) {}
484 // WINDOW *subpad (WINDOW *, int, int, int, int) {}
485 WINDOW *subwin(WINDOW *w, int l, int c, int y, int x)
487 return derwin(w, l, c, y - w->_begy, x - w->_begx);
489 // int syncok (WINDOW *, bool) {}
490 // chtype termattrs (void) {}
491 // char *termname (void) {}
492 // int typeahead (int) {}
493 int ungetch(int ch) { /* TODO */ return ERR; }
494 // void use_env (bool) {}
495 // int vidattr (chtype) {}
496 // int vidputs (chtype, int (*)(int)) {}
497 int vwprintw(WINDOW *win, const char *fmt, va_list argp)
499 vsprintf((char *)&sprintf_tmp, fmt, argp);
501 /* TODO: Error handling? */
502 return waddstr(win, (char *)&sprintf_tmp);
504 // int vwscanw (WINDOW *, NCURSES_CONST char *,va_list) {}
505 int waddch(WINDOW *win, const chtype ch)
507 int code = ERR;
508 // NCURSES_CH_T wch;
509 // SetChar2(wch, ch);
511 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
512 win->_line[win->_cury].firstchar > win->_curx)
513 win->_line[win->_cury].firstchar = win->_curx;
515 win->_line[win->_cury].text[win->_curx].chars[0] =
516 ((ch) & (chtype)A_CHARTEXT);
518 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
519 win->_line[win->_cury].text[win->_curx].attr |=
520 ((ch) & (chtype)A_ATTRIBUTES);
522 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
523 win->_line[win->_cury].lastchar < win->_curx)
524 win->_line[win->_cury].lastchar = win->_curx;
526 win->_curx++; // FIXME
528 // if (win && (waddch_nosync(win, wch) != ERR)) {
529 // _nc_synchook(win);
530 // code = OK;
531 // }
533 return code;
535 // int waddchnstr (WINDOW *,const chtype *,int) {}
536 int waddnstr(WINDOW *win, const char *astr, int n)
538 int code = OK;
539 const char *str = astr;
541 if (!str)
542 return ERR;
544 if (n < 0)
545 n = strlen(astr);
547 if (win->_line[win->_cury].firstchar == _NOCHANGE ||
548 win->_line[win->_cury].firstchar > win->_curx)
549 win->_line[win->_cury].firstchar = win->_curx;
551 while ((n-- > 0) && (*str != '\0')) {
552 // while (*str != '\0') {
553 win->_line[win->_cury].text[win->_curx].chars[0] = *str++;
554 win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win)
556 win->_curx++; // FIXME
558 // NCURSES_CH_T ch;
559 // SetChar(ch, UChar(*str++), A_NORMAL);
560 // if (_nc_waddch_nosync(win, ch) == ERR) {
561 // code = ERR;
562 // break;
563 // }
566 if (win->_line[win->_cury].lastchar == _NOCHANGE ||
567 win->_line[win->_cury].lastchar < win->_curx)
568 win->_line[win->_cury].lastchar = win->_curx;
570 return code;
572 int wattr_on(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
574 if (at & A_COLOR)
575 win->_color = PAIR_NUMBER(at);
576 // toggle_attr_on(WINDOW_ATTRS(win), at);
577 return OK;
579 int wattr_off(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
581 if (at & A_COLOR)
582 win->_color = 0;
583 // toggle_attr_off(WINDOW_ATTRS(win), at);
584 return 0;
586 // int wbkgd (WINDOW *, chtype) {}
587 void wbkgdset(WINDOW *win, chtype ch) { /* TODO */ }
589 int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs,
590 chtype tl, chtype tr, chtype bl, chtype br)
592 int x, y;
594 if (ls == 0) ls = ACS_VLINE;
595 if (rs == 0) rs = ACS_VLINE;
596 if (ts == 0) ts = ACS_HLINE;
597 if (bs == 0) bs = ACS_HLINE;
598 if (tl == 0) tl = ACS_ULCORNER;
599 if (tr == 0) tr = ACS_URCORNER;
600 if (bl == 0) bl = ACS_LLCORNER;
601 if (br == 0) br = ACS_LRCORNER;
603 for(y = 0; y <= win->_maxy; y++) {
605 if (y == 0) {
606 mvwaddch(win, y, 0, tl);
608 for(x = 1; x < win->_maxx; x++)
609 mvwaddch(win, y, x, ts);
611 mvwaddch(win, y, win->_maxx, tr);
613 else if (y == win->_maxy) {
614 mvwaddch(win, y, 0, bl);
616 for(x = 1; x < win->_maxx; x++)
617 mvwaddch(win, y, x, bs);
619 mvwaddch(win, y, win->_maxx, br);
621 else {
622 mvwaddch(win, y, 0, ls);
623 mvwaddch(win, y, win->_maxx, rs);
627 return OK;
630 // int wchgat (WINDOW *, int, attr_t, short, const void *) {}
631 /* D */ int wclear(WINDOW *win)
633 if (werase(win) == ERR)
634 return ERR;
635 win->_clear = TRUE;
636 return OK;
638 // int wclrtobot (WINDOW *) {}
639 int wclrtoeol(WINDOW *win) { /* TODO */ return ERR; }
640 int wcolor_set(WINDOW *win, short color_pair_number, void *opts)
642 if (!opts && (color_pair_number >= 0)
643 && (color_pair_number < COLOR_PAIRS)) {
644 SET_WINDOW_PAIR(win, color_pair_number);
645 if_EXT_COLORS(win->_color = color_pair_number);
646 return OK;
648 return ERR;
650 // void wcursyncup (WINDOW *) {}
651 // int wdelch (WINDOW *) {}
652 // int wechochar (WINDOW *, const chtype) {}
653 int werase(WINDOW *win)
655 int x, y;
656 for (y = 0; y <= win->_maxy; y++) {
657 for (x = 0; x <= win->_maxx; x++) {
658 win->_line[y].text[x].chars[0] = ' ';
659 win->_line[y].text[x].attr = WINDOW_ATTRS(win);
661 // Should we check instead?
662 win->_line[y].firstchar = 0;
663 win->_line[y].lastchar = win->_maxx;
665 return OK;
667 // int wgetnstr (WINDOW *,char *,int) {}
668 int whline(WINDOW *win, chtype ch, int n)
670 NCURSES_SIZE_T start, end;
671 struct ldat *line = &(win->_line[win->_cury]);
672 NCURSES_CH_T wch;
674 start = win->_curx;
675 end = start + n - 1;
676 if (end > win->_maxx)
677 end = win->_maxx;
679 CHANGED_RANGE(line, start, end);
681 //// TODO:
682 //// if (ch == 0)
683 //// SetChar2(wch, ACS_HLINE);
684 //// else
685 //// SetChar2(wch, ch);
686 // Ugly hack:
687 wch.chars[0] = ((ch) & (chtype)A_CHARTEXT);
688 wch.attr = ((ch) & (chtype)A_ATTRIBUTES);
689 wch = _nc_render(win, wch);
691 while (end >= start) {
692 line->text[end] = wch;
693 end--;
696 //// _nc_synchook(win);
698 return OK;
700 /* D */ chtype winch(WINDOW *win)
702 //// TODO
703 // return (CharOf(win->_line[win->_cury].text[win->_curx]) |
704 // AttrOf(win->_line[win->_cury].text[win->_curx]));
705 return OK; // FIXME
707 // int winchnstr (WINDOW *, chtype *, int) {}
708 // int winnstr (WINDOW *, char *, int) {}
709 // int winsch (WINDOW *, chtype) {}
710 // int winsdelln (WINDOW *,int) {}
711 // int winsnstr (WINDOW *, const char *,int) {}
712 /* D */ int wmove(WINDOW *win, int y, int x)
714 if (!LEGALYX(win, y, x))
715 return ERR;
716 win->_curx = (NCURSES_SIZE_T) x;
717 win->_cury = (NCURSES_SIZE_T) y;
718 win->_flags &= ~_WRAPPED;
719 win->_flags |= _HASMOVED;
720 return OK;
723 #define SWAP_RED_BLUE(c) \
724 (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
725 int wnoutrefresh(WINDOW *win)
727 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
728 // FIXME.
729 int serial_is_bold = 0;
730 int serial_is_reverse = 0;
731 int serial_is_altcharset = 0;
732 int serial_cur_pair = 0;
734 int need_altcharset;
735 short fg, bg;
736 #endif
737 int x, y;
738 chtype ch;
740 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
741 serial_end_bold();
742 serial_end_altcharset();
743 #endif
745 for (y = 0; y <= win->_maxy; y++) {
747 if (win->_line[y].firstchar == _NOCHANGE)
748 continue;
750 /* Position the serial cursor */
752 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
753 if (curses_flags & F_ENABLE_SERIAL)
754 serial_set_cursor(win->_begy + y, win->_begx +
755 win->_line[y].firstchar);
756 #endif
758 for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
759 attr_t attr = win->_line[y].text[x].attr;
761 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
762 if (curses_flags & F_ENABLE_SERIAL) {
763 ch = win->_line[y].text[x].chars[0];
765 if (attr & A_BOLD) {
766 if (!serial_is_bold) {
767 serial_start_bold();
768 serial_is_bold = 1;
770 } else {
771 if (serial_is_bold) {
772 serial_end_bold();
773 serial_is_bold = 0;
774 /* work around serial.c
775 * shortcoming:
777 serial_is_reverse = 0;
778 serial_cur_pair = 0;
782 if (attr & A_REVERSE) {
783 if (!serial_is_reverse) {
784 serial_start_reverse();
785 serial_is_reverse = 1;
787 } else {
788 if (serial_is_reverse) {
789 serial_end_reverse();
790 serial_is_reverse = 0;
791 /* work around serial.c
792 * shortcoming:
794 serial_is_bold = 0;
795 serial_cur_pair = 0;
799 need_altcharset = 0;
800 if (attr & A_ALTCHARSET) {
801 if (serial_acs_map[ch & 0x7f]) {
802 ch = serial_acs_map[ch & 0x7f];
803 need_altcharset = 1;
804 } else
805 ch = fallback_acs_map[ch & 0x7f];
807 if (need_altcharset && !serial_is_altcharset) {
808 serial_start_altcharset();
809 serial_is_altcharset = 1;
811 if (!need_altcharset && serial_is_altcharset) {
812 serial_end_altcharset();
813 serial_is_altcharset = 0;
816 if (serial_cur_pair != PAIR_NUMBER(attr)) {
817 pair_content(PAIR_NUMBER(attr),
818 &fg, &bg);
819 serial_set_color(fg, bg);
820 serial_cur_pair = PAIR_NUMBER(attr);
823 serial_putchar(ch);
826 #endif
827 #if IS_ENABLED(CONFIG_LP_VIDEO_CONSOLE)
828 unsigned int c =
829 ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
831 c = SWAP_RED_BLUE(c);
833 if (curses_flags & F_ENABLE_CONSOLE) {
834 ch = win->_line[y].text[x].chars[0];
836 /* Handle some of the attributes. */
837 if (attr & A_BOLD)
838 c |= 0x0800;
839 if (attr & A_DIM)
840 c &= ~0x800;
841 if (attr & A_REVERSE) {
842 unsigned char tmp = (c >> 8) & 0xf;
843 c = (c >> 4) & 0xf00;
844 c |= tmp << 12;
846 if (attr & A_ALTCHARSET) {
847 if (console_acs_map[ch & 0x7f])
848 ch = console_acs_map[ch & 0x7f];
849 else
850 ch = fallback_acs_map[ch & 0x7f];
854 * FIXME: Somewhere along the line, the
855 * character value is getting sign-extented.
856 * For now grab just the 8 bit character,
857 * but this will break wide characters!
859 c |= (chtype) (ch & 0xff);
860 video_console_putc(win->_begy + y, win->_begx + x, c);
862 #endif
864 win->_line[y].firstchar = _NOCHANGE;
865 win->_line[y].lastchar = _NOCHANGE;
868 #if IS_ENABLED(CONFIG_LP_SERIAL_CONSOLE)
869 if (curses_flags & F_ENABLE_SERIAL)
870 serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
871 #endif
873 #if IS_ENABLED(CONFIG_LP_VIDEO_CONSOLE)
874 if (curses_flags & F_ENABLE_CONSOLE)
875 video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
876 #endif
878 return OK;
880 int wprintw(WINDOW *win, const char *fmt, ...)
882 va_list argp;
883 int code;
885 va_start(argp, fmt);
886 code = vwprintw(win, fmt, argp);
887 va_end(argp);
889 return code;
892 int wredrawln (WINDOW *win, int beg_line, int num_lines)
894 int i;
896 for (i = beg_line; i < beg_line + num_lines; i++) {
897 win->_line[i].firstchar = 0;
898 win->_line[i].lastchar = win->_maxx;
901 return OK;
904 int wrefresh(WINDOW *win)
906 // FIXME
907 return wnoutrefresh(win);
909 // XXX
910 int code;
912 if (win == curscr) {
913 curscr->_clear = TRUE;
914 // code = doupdate();
915 } else if ((code = wnoutrefresh(win)) == OK) {
916 if (win->_clear)
917 newscr->_clear = TRUE;
918 // code = doupdate();
920 * Reset the clearok() flag in case it was set for the special
921 * case in hardscroll.c (if we don't reset it here, we'll get 2
922 * refreshes because the flag is copied from stdscr to newscr).
923 * Resetting the flag shouldn't do any harm, anyway.
925 win->_clear = FALSE;
928 return code;
930 // int wscanw (WINDOW *, NCURSES_CONST char *,...) {}
931 int wscrl(WINDOW *win, int n)
933 int x, y;
935 if (!win->_scroll)
936 return ERR;
938 if (n == 0)
939 return OK;
941 for (y = 0; y <= (win->_maxy - n); y++) {
942 win->_line[y].firstchar = win->_line[y + n].firstchar;
943 win->_line[y].lastchar = win->_line[y + n].lastchar;
944 for (x = 0; x <= win->_maxx; x++) {
945 if ((win->_line[y].text[x].chars[0] != win->_line[y + n].text[x].chars[0]) ||
946 (win->_line[y].text[x].attr != win->_line[y + n].text[x].attr)) {
947 if (win->_line[y].firstchar == _NOCHANGE)
948 win->_line[y].firstchar = x;
950 win->_line[y].lastchar = x;
952 win->_line[y].text[x].chars[0] = win->_line[y + n].text[x].chars[0];
953 win->_line[y].text[x].attr = win->_line[y + n].text[x].attr;
958 for (y = (win->_maxy+1 - n); y <= win->_maxy; y++) {
959 for (x = 0; x <= win->_maxx; x++) {
960 if ((win->_line[y].text[x].chars[0] != ' ') ||
961 (win->_line[y].text[x].attr != A_NORMAL)) {
962 if (win->_line[y].firstchar == _NOCHANGE)
963 win->_line[y].firstchar = x;
965 win->_line[y].lastchar = x;
967 win->_line[y].text[x].chars[0] = ' ';
968 win->_line[y].text[x].attr = A_NORMAL;
973 // _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd);
974 // _nc_synchook(win);
976 return OK;
978 int wsetscrreg(WINDOW *win, int top, int bottom)
980 if (top >= 0 && top <= win->_maxy && bottom >= 0 &&
981 bottom <= win->_maxy && bottom > top) {
982 win->_regtop = (NCURSES_SIZE_T) top;
983 win->_regbottom = (NCURSES_SIZE_T) bottom;
984 return OK;
986 return ERR;
988 // void wsyncdown (WINDOW *) {}
989 // void wsyncup (WINDOW *) {}
990 /* D */ void wtimeout(WINDOW *win, int _delay) { win->_delay = _delay; }
991 /* D */ int wtouchln(WINDOW *win, int y, int n, int changed)
993 int i;
995 // if ((n < 0) || (y < 0) || (y > win->_maxy))
996 // return ERR;
998 for (i = y; i < y + n; i++) {
999 if (i > win->_maxy)
1000 break;
1001 win->_line[i].firstchar = changed ? 0 : _NOCHANGE;
1002 win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE;
1004 return OK;
1006 // int wvline (WINDOW *,chtype,int) {}
1007 // int tigetflag (NCURSES_CONST char *) {}
1008 // int tigetnum (NCURSES_CONST char *) {}
1009 // char *tigetstr (NCURSES_CONST char *) {}
1010 // int putp (const char *) {}
1011 // #if NCURSES_TPARM_VARARGS
1012 // char *tparm (NCURSES_CONST char *, ...) {}
1013 // #else
1014 // char *tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long) {}
1015 // char *tparm_varargs (NCURSES_CONST char *, ...) {}
1016 // #endif