xref: /aosp_15_r20/external/coreboot/payloads/libpayload/curses/pdcurses-backend/pdcdisp.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* Public Domain Curses */
2 /* This file is BSD licensed, Copyright 2011 secunet AG */
3 
4 #include "lppdc.h"
5 #include <libpayload.h>
6 
7 /* ACS definitions originally by [email protected] -- these
8    match code page 437 and compatible pages (CP850, CP852, etc.) */
9 
10 #ifdef CHTYPE_LONG
11 
12 # define A(x) ((chtype)x | A_ALTCHARSET)
13 
14 chtype acs_map[128] =
15 {
16     A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8), A(9), A(10),
17     A(11), A(12), A(13), A(14), A(15), A(16), A(17), A(18), A(19),
18     A(20), A(21), A(22), A(23), A(24), A(25), A(26), A(27), A(28),
19     A(29), A(30), A(31), ' ', '!', '"', '#', '$', '%', '&', '\'', '(',
20     ')', '*',
21 
22     A(0x1a), A(0x1b), A(0x18), A(0x19),
23 
24     '/',
25 
26     0xdb,
27 
28     '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
29     '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
30     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
31     'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
32 
33     A(0x04), 0xb1,
34 
35     'b', 'c', 'd', 'e',
36 
37     0xf8, 0xf1, 0xb0, A(0x0f), 0xd9, 0xbf, 0xda, 0xc0, 0xc5, 0x2d, 0x2d,
38     0xc4, 0x2d, 0x5f, 0xc3, 0xb4, 0xc1, 0xc2, 0xb3, 0xf3, 0xf2, 0xe3,
39     0xd8, 0x9c, 0xf9,
40 
41     A(127)
42 };
43 
44 # undef A
45 
46 #endif
47 
48 /* See terminfo(5). */
49 chtype fallback_acs_map[128] =
50 	{
51 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
52 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
53 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
54 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
55 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
56 	' ',	' ',	' ',	'>',	'<',	'^',	'v',	' ',
57 	'#',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
58 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
59 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
60 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
61 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
62 	' ',	' ',	' ',	' ',	' ',	' ',	' ',	' ',
63 	'+',	':',	' ',	' ',	' ',	' ',	'\\',   '#',
64 	'#',	'#',	'+',	'+',	'+',	'+',	'+',	'~',
65 	'-',	'-',	'-',	'_',	'+',	'+',	'+',	'+',
66 	'|',	'<',	'>',	'*',	'!',	'f',	'o',	' ',
67 	};
68 
69 #if CONFIG(LP_SERIAL_CONSOLE)
70 #if CONFIG(LP_SERIAL_ACS_FALLBACK)
71 chtype serial_acs_map[128];
72 #else
73 /* See acsc of vt100. */
74 chtype serial_acs_map[128] =
75 	{
76 	0,	0,	0,	0,	0,	0,	0,	0,
77 	0,	0,	0,	0,	0,	0,	0,	0,
78 	0,	0,	0,	0,	0,	0,	0,	0,
79 	0,	0,	0,	0,	0,	0,	0,	0,
80 	0,	0,	0,	0,	0,	0,	0,	0,
81 	0,	0,	0,	0,	0,	0,	0,	0,
82 	0,	0,	0,	0,	0,	0,	0,	0,
83 	0,	0,	0,	0,	0,	0,	0,	0,
84 	0,	0,	0,	0,	0,	0,	0,	0,
85 	0,	0,	0,	0,	0,	0,	0,	0,
86 	0,	0,	0,	0,	0,	0,	0,	0,
87 	0,	0,	0,	0,	0,	0,	0,	0,
88 	'`',	'a',	0,	0,	0,	0,	'f',	'g',
89 	0,	0,	'j',	'k',	'l',	'm',	'n',	'o',
90 	'p',	'q',	'r',	's',	't',	'u',	'v',	'w',
91 	'x',	'y',	'z',	'{',	'|',	'}',	'~',	0,
92 	};
93 #endif
94 #endif
95 
96 #if CONFIG(LP_VIDEO_CONSOLE)
97 /* See acsc of linux. */
98 chtype console_acs_map[128] =
99 	{
100 	0,	0,	0,	0,	0,	0,	0,	0,
101 	0,	0,	0,	0,	0,	0,	0,	0,
102 	0,	0,	0,	0,	0,	0,	0,	0,
103 	0,	0,	0,	0,	0,	0,	0,	0,
104 	0,	0,	0,	0,	0,	0,	0,	0,
105 	0,	0,	0,	'\020', '\021', '\030', '\031',	0,
106 	'\333',	0,	0,	0,	0,	0,	0,	0,
107 	0,	0,	0,	0,	0,	0,	0,	0,
108 	0,	0,	0,	0,	0,	0,	0,	0,
109 	0,	0,	0,	0,	0,	0,	0,	0,
110 	0,	0,	0,	0,	0,	0,	0,	0,
111 	0,	0,	0,	0,	0,	0,	0,	0,
112 	'\004',	'\261',	0,	0,	0,	0,	'\370',	'\361',
113 	'\260',	'\316',	'\331',	'\277',	'\332',	'\300',	'\305',	'~',
114 	'\304',	'\304',	'\304',	'_',	'\303', '\264', '\301',	'\302',
115 	'\263',	'\363',	'\362',	'\343',	'\330',	'\234',	'\376',	0,
116 	};
117 #endif
118 
119 /* position hardware cursor at (y, x) */
120 
PDC_gotoyx(int row,int col)121 void PDC_gotoyx(int row, int col)
122 {
123     PDC_LOG(("PDC_gotoyx() - called: row %d col %d\n", row, col));
124 
125 #if CONFIG(LP_SERIAL_CONSOLE)
126     serial_set_cursor(col, row);
127 #endif
128 #if CONFIG(LP_VIDEO_CONSOLE)
129     video_console_set_cursor(col, row);
130 #endif
131 }
132 
133 /* update the given physical line to look like the corresponding line in
134    curscr */
135 
PDC_transform_line(int lineno,int x,int len,const chtype * srcp)136 void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
137 {
138     int j, ch, attr;
139 
140     PDC_LOG(("PDC_transform_line() - called: line %d, len %d, curses_flags %d\n", lineno, len, curses_flags));
141 
142 #if CONFIG(LP_SERIAL_CONSOLE)
143     int serial_is_bold = 0;
144     int serial_is_reverse = 0;
145     int serial_is_altcharset = 0;
146     int serial_cur_pair = 0;
147     int need_altcharset;
148 
149     if (curses_flags & F_ENABLE_SERIAL) {
150         serial_end_bold();
151         serial_end_altcharset();
152         serial_set_cursor(lineno, x);
153     }
154 #endif
155 
156     for (j = 0; j < len; j++)
157     {
158 	ch = srcp[j];
159 	attr = ch;
160 #if CONFIG(LP_SERIAL_CONSOLE)
161 	if (curses_flags & F_ENABLE_SERIAL) {
162 		if (attr & A_BOLD) {
163 			if (!serial_is_bold) {
164 				serial_start_bold();
165 				serial_is_bold = 1;
166 			}
167 		} else {
168 			if (serial_is_bold) {
169 				serial_end_bold();
170 				serial_is_bold = 0;
171 				/* work around serial.c
172 				 * shortcoming:
173 				 */
174 				serial_is_reverse = 0;
175 				serial_cur_pair = 0;
176 			}
177 		}
178 
179 		if (attr & A_REVERSE) {
180 			if (!serial_is_reverse) {
181 				serial_start_reverse();
182 				serial_is_reverse = 1;
183 			}
184 		} else {
185 			if (serial_is_reverse) {
186 				serial_end_reverse();
187 				serial_is_reverse = 0;
188 				/* work around serial.c
189 				 * shortcoming:
190 				 */
191 				serial_is_bold = 0;
192 				serial_cur_pair = 0;
193 			}
194 		}
195 
196 		need_altcharset = 0;
197 		if (attr & A_ALTCHARSET) {
198 			if (serial_acs_map[ch & 0x7f]) {
199 				ch = serial_acs_map[ch & 0x7f];
200 				need_altcharset = 1;
201 			} else
202 				ch = fallback_acs_map[ch & 0x7f];
203 		}
204 		if (need_altcharset && !serial_is_altcharset) {
205 			serial_start_altcharset();
206 			serial_is_altcharset = 1;
207 		}
208 		if (!need_altcharset && serial_is_altcharset) {
209 			serial_end_altcharset();
210 			serial_is_altcharset = 0;
211 		}
212 
213 		if (serial_cur_pair != PAIR_NUMBER(attr)) {
214 			short int fg, bg;
215 			if (pair_content(PAIR_NUMBER(attr), &fg, &bg) == OK)
216 				serial_set_color(fg, bg);
217 			serial_cur_pair = PAIR_NUMBER(attr);
218 		}
219 
220 		serial_putchar(ch & 0xff);
221 
222 	}
223 #endif
224 #if CONFIG(LP_VIDEO_CONSOLE)
225 	unsigned char c = pdc_atrtab[srcp[j] >> PDC_ATTR_SHIFT];
226 
227 	if (curses_flags & F_ENABLE_CONSOLE) {
228 		if (attr & A_ALTCHARSET) {
229 			if (console_acs_map[ch & 0x7f])
230 				ch = console_acs_map[ch & 0x7f];
231 			else
232 				ch = fallback_acs_map[ch & 0x7f];
233 		}
234 
235 		/*
236 		 * FIXME: Somewhere along the line, the
237 		 * character value is getting sign-extented.
238 		 * For now grab just the 8 bit character,
239 		 * but this will break wide characters!
240 		 */
241 		video_console_putc(lineno, x + j, (c << 8) | ( ch & 0xff));
242 	}
243 #endif
244     }
245 }
246