Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / hci / mucurses / ansi_screen.c
1 #include <stdio.h>
2 #include <curses.h>
3 #include <ipxe/ansicol.h>
4 #include <ipxe/console.h>
5
6 FILE_LICENCE ( GPL2_OR_LATER );
7
8 static void ansiscr_reset(struct _curses_screen *scr) __nonnull;
9 static void ansiscr_movetoyx(struct _curses_screen *scr,
10                                unsigned int y, unsigned int x) __nonnull;
11 static void ansiscr_putc(struct _curses_screen *scr, chtype c) __nonnull;
12
13 static unsigned int saved_usage;
14
15 static void ansiscr_attrs ( struct _curses_screen *scr, attr_t attrs ) {
16         int bold = ( attrs & A_BOLD );
17         attr_t cpair = PAIR_NUMBER ( attrs );
18
19         if ( scr->attrs != attrs ) {
20                 scr->attrs = attrs;
21                 /* Reset attributes and set/clear bold as appropriate */
22                 printf ( "\033[0;%dm", ( bold ? 1 : 22 ) );
23                 /* Set foreground and background colours */
24                 ansicol_set_pair ( cpair );
25         }
26 }
27
28 static void ansiscr_reset ( struct _curses_screen *scr ) {
29         /* Reset terminal attributes and clear screen */
30         scr->attrs = 0;
31         scr->curs_x = 0;
32         scr->curs_y = 0;
33         printf ( "\0330m" );
34         ansicol_set_pair ( CPAIR_DEFAULT );
35         printf ( "\033[2J" );
36 }
37
38 static void ansiscr_init ( struct _curses_screen *scr ) {
39         saved_usage = console_set_usage ( CONSOLE_USAGE_TUI );
40         ansiscr_reset ( scr );
41 }
42
43 static void ansiscr_exit ( struct _curses_screen *scr ) {
44         ansiscr_reset ( scr );
45         console_set_usage ( saved_usage );
46 }
47
48 static void ansiscr_erase ( struct _curses_screen *scr, attr_t attrs ) {
49         ansiscr_attrs ( scr, attrs );
50         printf ( "\033[2J" );
51 }
52
53 static void ansiscr_movetoyx ( struct _curses_screen *scr,
54                                unsigned int y, unsigned int x ) {
55         if ( ( x != scr->curs_x ) || ( y != scr->curs_y ) ) {
56                 /* ANSI escape sequence to update cursor position */
57                 printf ( "\033[%d;%dH", ( y + 1 ), ( x + 1 ) );
58                 scr->curs_x = x;
59                 scr->curs_y = y;
60         }
61 }
62
63 static void ansiscr_putc ( struct _curses_screen *scr, chtype c ) {
64         unsigned int character = ( c & A_CHARTEXT );
65         attr_t attrs = ( c & ( A_ATTRIBUTES | A_COLOR ) );
66
67         /* Update attributes if changed */
68         ansiscr_attrs ( scr, attrs );
69
70         /* Print the actual character */
71         putchar ( character );
72
73         /* Update expected cursor position */
74         if ( ++(scr->curs_x) == COLS ) {
75                 scr->curs_x = 0;
76                 ++scr->curs_y;
77         }
78 }
79
80 static int ansiscr_getc ( struct _curses_screen *scr __unused ) {
81         return getchar();
82 }
83
84 static bool ansiscr_peek ( struct _curses_screen *scr __unused ) {
85         return iskey();
86 }
87
88 static void ansiscr_cursor ( struct _curses_screen *scr __unused,
89                              int visibility ) {
90         printf ( "\033[?25%c", ( visibility ? 'h' : 'l' ) );
91 }
92
93 SCREEN _ansi_screen = {
94         .init           = ansiscr_init,
95         .exit           = ansiscr_exit,
96         .erase          = ansiscr_erase,
97         .movetoyx       = ansiscr_movetoyx,
98         .putc           = ansiscr_putc,
99         .getc           = ansiscr_getc,
100         .peek           = ansiscr_peek,
101         .cursor         = ansiscr_cursor,
102 };