xref: /dflybsd-src/stand/boot/efi/libefi/efi_console.c (revision 479ab7f0492f2a51b48e8537e4f1dc686fc6014b)
1*479ab7f0SSascha Wildner /*-
2*479ab7f0SSascha Wildner  * Copyright (c) 2000 Doug Rabson
3*479ab7f0SSascha Wildner  * All rights reserved.
4*479ab7f0SSascha Wildner  *
5*479ab7f0SSascha Wildner  * Redistribution and use in source and binary forms, with or without
6*479ab7f0SSascha Wildner  * modification, are permitted provided that the following conditions
7*479ab7f0SSascha Wildner  * are met:
8*479ab7f0SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
9*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer.
10*479ab7f0SSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
11*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
12*479ab7f0SSascha Wildner  *    documentation and/or other materials provided with the distribution.
13*479ab7f0SSascha Wildner  *
14*479ab7f0SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*479ab7f0SSascha Wildner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*479ab7f0SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*479ab7f0SSascha Wildner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*479ab7f0SSascha Wildner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*479ab7f0SSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*479ab7f0SSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*479ab7f0SSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*479ab7f0SSascha Wildner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*479ab7f0SSascha Wildner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*479ab7f0SSascha Wildner  * SUCH DAMAGE.
25*479ab7f0SSascha Wildner  */
26*479ab7f0SSascha Wildner 
27*479ab7f0SSascha Wildner #include <sys/cdefs.h>
28*479ab7f0SSascha Wildner __FBSDID("$FreeBSD: head/sys/boot/efi/libefi/efi_console.c 293724 2016-01-12 02:17:39Z smh $");
29*479ab7f0SSascha Wildner 
30*479ab7f0SSascha Wildner #include <efi.h>
31*479ab7f0SSascha Wildner #include <efilib.h>
32*479ab7f0SSascha Wildner 
33*479ab7f0SSascha Wildner #include "bootstrap.h"
34*479ab7f0SSascha Wildner 
35*479ab7f0SSascha Wildner static SIMPLE_TEXT_OUTPUT_INTERFACE	*conout;
36*479ab7f0SSascha Wildner static SIMPLE_INPUT_INTERFACE		*conin;
37*479ab7f0SSascha Wildner 
38*479ab7f0SSascha Wildner #ifdef TERM_EMU
39*479ab7f0SSascha Wildner #define	DEFAULT_FGCOLOR	EFI_LIGHTGRAY
40*479ab7f0SSascha Wildner #define	DEFAULT_BGCOLOR	EFI_BLACK
41*479ab7f0SSascha Wildner 
42*479ab7f0SSascha Wildner #define	MAXARGS	8
43*479ab7f0SSascha Wildner static int args[MAXARGS], argc;
44*479ab7f0SSascha Wildner static int fg_c, bg_c, curx, cury;
45*479ab7f0SSascha Wildner static int esc;
46*479ab7f0SSascha Wildner 
47*479ab7f0SSascha Wildner void get_pos(int *x, int *y);
48*479ab7f0SSascha Wildner void curs_move(int *_x, int *_y, int x, int y);
49*479ab7f0SSascha Wildner static void CL(int);
50*479ab7f0SSascha Wildner void HO(void);
51*479ab7f0SSascha Wildner void end_term(void);
52*479ab7f0SSascha Wildner #endif
53*479ab7f0SSascha Wildner 
54*479ab7f0SSascha Wildner static void efi_cons_probe(struct console *);
55*479ab7f0SSascha Wildner static int efi_cons_init(int);
56*479ab7f0SSascha Wildner void efi_cons_putchar(int);
57*479ab7f0SSascha Wildner int efi_cons_getchar(void);
58*479ab7f0SSascha Wildner void efi_cons_efiputchar(int);
59*479ab7f0SSascha Wildner int efi_cons_poll(void);
60*479ab7f0SSascha Wildner 
61*479ab7f0SSascha Wildner struct console efi_console = {
62*479ab7f0SSascha Wildner 	"efi",
63*479ab7f0SSascha Wildner 	"EFI console",
64*479ab7f0SSascha Wildner 	0,
65*479ab7f0SSascha Wildner 	efi_cons_probe,
66*479ab7f0SSascha Wildner 	efi_cons_init,
67*479ab7f0SSascha Wildner 	efi_cons_putchar,
68*479ab7f0SSascha Wildner 	efi_cons_getchar,
69*479ab7f0SSascha Wildner 	efi_cons_poll
70*479ab7f0SSascha Wildner };
71*479ab7f0SSascha Wildner 
72*479ab7f0SSascha Wildner #ifdef TERM_EMU
73*479ab7f0SSascha Wildner 
74*479ab7f0SSascha Wildner /* Get cursor position. */
75*479ab7f0SSascha Wildner void
get_pos(int * x,int * y)76*479ab7f0SSascha Wildner get_pos(int *x, int *y)
77*479ab7f0SSascha Wildner {
78*479ab7f0SSascha Wildner 	*x = conout->Mode->CursorColumn;
79*479ab7f0SSascha Wildner 	*y = conout->Mode->CursorRow;
80*479ab7f0SSascha Wildner }
81*479ab7f0SSascha Wildner 
82*479ab7f0SSascha Wildner /* Move cursor to x rows and y cols (0-based). */
83*479ab7f0SSascha Wildner void
curs_move(int * _x,int * _y,int x,int y)84*479ab7f0SSascha Wildner curs_move(int *_x, int *_y, int x, int y)
85*479ab7f0SSascha Wildner {
86*479ab7f0SSascha Wildner 	conout->SetCursorPosition(conout, x, y);
87*479ab7f0SSascha Wildner 	if (_x != NULL)
88*479ab7f0SSascha Wildner 		*_x = conout->Mode->CursorColumn;
89*479ab7f0SSascha Wildner 	if (_y != NULL)
90*479ab7f0SSascha Wildner 		*_y = conout->Mode->CursorRow;
91*479ab7f0SSascha Wildner }
92*479ab7f0SSascha Wildner 
93*479ab7f0SSascha Wildner /* Clear internal state of the terminal emulation code. */
94*479ab7f0SSascha Wildner void
end_term(void)95*479ab7f0SSascha Wildner end_term(void)
96*479ab7f0SSascha Wildner {
97*479ab7f0SSascha Wildner 	esc = 0;
98*479ab7f0SSascha Wildner 	argc = -1;
99*479ab7f0SSascha Wildner }
100*479ab7f0SSascha Wildner 
101*479ab7f0SSascha Wildner #endif
102*479ab7f0SSascha Wildner 
103*479ab7f0SSascha Wildner static void
efi_cons_probe(struct console * cp)104*479ab7f0SSascha Wildner efi_cons_probe(struct console *cp)
105*479ab7f0SSascha Wildner {
106*479ab7f0SSascha Wildner 	conout = ST->ConOut;
107*479ab7f0SSascha Wildner 	conin = ST->ConIn;
108*479ab7f0SSascha Wildner 	cp->c_flags |= C_PRESENTIN | C_PRESENTOUT;
109*479ab7f0SSascha Wildner }
110*479ab7f0SSascha Wildner 
111*479ab7f0SSascha Wildner static int
efi_cons_init(int arg)112*479ab7f0SSascha Wildner efi_cons_init(int arg)
113*479ab7f0SSascha Wildner {
114*479ab7f0SSascha Wildner 	conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
115*479ab7f0SSascha Wildner 	    DEFAULT_BGCOLOR));
116*479ab7f0SSascha Wildner #ifdef TERM_EMU
117*479ab7f0SSascha Wildner 	end_term();
118*479ab7f0SSascha Wildner 	get_pos(&curx, &cury);
119*479ab7f0SSascha Wildner 	curs_move(&curx, &cury, curx, cury);
120*479ab7f0SSascha Wildner 	fg_c = DEFAULT_FGCOLOR;
121*479ab7f0SSascha Wildner 	bg_c = DEFAULT_BGCOLOR;
122*479ab7f0SSascha Wildner #endif
123*479ab7f0SSascha Wildner 	conout->EnableCursor(conout, TRUE);
124*479ab7f0SSascha Wildner 	return 0;
125*479ab7f0SSascha Wildner }
126*479ab7f0SSascha Wildner 
127*479ab7f0SSascha Wildner static void
efi_cons_rawputchar(int c)128*479ab7f0SSascha Wildner efi_cons_rawputchar(int c)
129*479ab7f0SSascha Wildner {
130*479ab7f0SSascha Wildner 	int i;
131*479ab7f0SSascha Wildner 	UINTN x, y;
132*479ab7f0SSascha Wildner 	conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
133*479ab7f0SSascha Wildner 
134*479ab7f0SSascha Wildner 	if (c == '\t')
135*479ab7f0SSascha Wildner 		/* XXX lame tab expansion */
136*479ab7f0SSascha Wildner 		for (i = 0; i < 8; i++)
137*479ab7f0SSascha Wildner 			efi_cons_rawputchar(' ');
138*479ab7f0SSascha Wildner 	else {
139*479ab7f0SSascha Wildner #ifndef	TERM_EMU
140*479ab7f0SSascha Wildner 		if (c == '\n')
141*479ab7f0SSascha Wildner 			efi_cons_efiputchar('\r');
142*479ab7f0SSascha Wildner 		else
143*479ab7f0SSascha Wildner 			efi_cons_efiputchar(c);
144*479ab7f0SSascha Wildner #else
145*479ab7f0SSascha Wildner 		switch (c) {
146*479ab7f0SSascha Wildner 		case '\r':
147*479ab7f0SSascha Wildner 			curx = 0;
148*479ab7f0SSascha Wildner 			curs_move(&curx, &cury, curx, cury);
149*479ab7f0SSascha Wildner 			return;
150*479ab7f0SSascha Wildner 		case '\n':
151*479ab7f0SSascha Wildner 			cury++;
152*479ab7f0SSascha Wildner 			if (cury >= y) {
153*479ab7f0SSascha Wildner 				efi_cons_efiputchar('\n');
154*479ab7f0SSascha Wildner 				cury--;
155*479ab7f0SSascha Wildner 			} else
156*479ab7f0SSascha Wildner 				curs_move(&curx, &cury, curx, cury);
157*479ab7f0SSascha Wildner 			return;
158*479ab7f0SSascha Wildner 		case '\b':
159*479ab7f0SSascha Wildner 			if (curx > 0) {
160*479ab7f0SSascha Wildner 				curx--;
161*479ab7f0SSascha Wildner 				curs_move(&curx, &cury, curx, cury);
162*479ab7f0SSascha Wildner 			}
163*479ab7f0SSascha Wildner 			return;
164*479ab7f0SSascha Wildner 		default:
165*479ab7f0SSascha Wildner 			efi_cons_efiputchar(c);
166*479ab7f0SSascha Wildner 			curx++;
167*479ab7f0SSascha Wildner 			if (curx > x-1) {
168*479ab7f0SSascha Wildner 				curx = 0;
169*479ab7f0SSascha Wildner 				cury++;
170*479ab7f0SSascha Wildner 			}
171*479ab7f0SSascha Wildner 			if (cury > y-1) {
172*479ab7f0SSascha Wildner 				curx = 0;
173*479ab7f0SSascha Wildner 				cury--;
174*479ab7f0SSascha Wildner 			}
175*479ab7f0SSascha Wildner 		}
176*479ab7f0SSascha Wildner 		curs_move(&curx, &cury, curx, cury);
177*479ab7f0SSascha Wildner #endif
178*479ab7f0SSascha Wildner 	}
179*479ab7f0SSascha Wildner }
180*479ab7f0SSascha Wildner 
181*479ab7f0SSascha Wildner /* Gracefully exit ESC-sequence processing in case of misunderstanding. */
182*479ab7f0SSascha Wildner static void
bail_out(int c)183*479ab7f0SSascha Wildner bail_out(int c)
184*479ab7f0SSascha Wildner {
185*479ab7f0SSascha Wildner 	char buf[16], *ch;
186*479ab7f0SSascha Wildner 	int i;
187*479ab7f0SSascha Wildner 
188*479ab7f0SSascha Wildner 	if (esc) {
189*479ab7f0SSascha Wildner 		efi_cons_rawputchar('\033');
190*479ab7f0SSascha Wildner 		if (esc != '\033')
191*479ab7f0SSascha Wildner 			efi_cons_rawputchar(esc);
192*479ab7f0SSascha Wildner 		for (i = 0; i <= argc; ++i) {
193*479ab7f0SSascha Wildner 			sprintf(buf, "%d", args[i]);
194*479ab7f0SSascha Wildner 			ch = buf;
195*479ab7f0SSascha Wildner 			while (*ch)
196*479ab7f0SSascha Wildner 				efi_cons_rawputchar(*ch++);
197*479ab7f0SSascha Wildner 		}
198*479ab7f0SSascha Wildner 	}
199*479ab7f0SSascha Wildner 	efi_cons_rawputchar(c);
200*479ab7f0SSascha Wildner 	end_term();
201*479ab7f0SSascha Wildner }
202*479ab7f0SSascha Wildner 
203*479ab7f0SSascha Wildner /* Clear display from current position to end of screen. */
204*479ab7f0SSascha Wildner static void
CD(void)205*479ab7f0SSascha Wildner CD(void) {
206*479ab7f0SSascha Wildner 	int i;
207*479ab7f0SSascha Wildner 	UINTN x, y;
208*479ab7f0SSascha Wildner 
209*479ab7f0SSascha Wildner 	get_pos(&curx, &cury);
210*479ab7f0SSascha Wildner 	if (curx == 0 && cury == 0) {
211*479ab7f0SSascha Wildner 		conout->ClearScreen(conout);
212*479ab7f0SSascha Wildner 		end_term();
213*479ab7f0SSascha Wildner 		return;
214*479ab7f0SSascha Wildner 	}
215*479ab7f0SSascha Wildner 
216*479ab7f0SSascha Wildner 	conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
217*479ab7f0SSascha Wildner 	CL(0);  /* clear current line from cursor to end */
218*479ab7f0SSascha Wildner 	for (i = cury + 1; i < y-1; i++) {
219*479ab7f0SSascha Wildner 		curs_move(NULL, NULL, 0, i);
220*479ab7f0SSascha Wildner 		CL(0);
221*479ab7f0SSascha Wildner 	}
222*479ab7f0SSascha Wildner 	curs_move(NULL, NULL, curx, cury);
223*479ab7f0SSascha Wildner 	end_term();
224*479ab7f0SSascha Wildner }
225*479ab7f0SSascha Wildner 
226*479ab7f0SSascha Wildner /*
227*479ab7f0SSascha Wildner  * Absolute cursor move to args[0] rows and args[1] columns
228*479ab7f0SSascha Wildner  * (the coordinates are 1-based).
229*479ab7f0SSascha Wildner  */
230*479ab7f0SSascha Wildner static void
CM(void)231*479ab7f0SSascha Wildner CM(void)
232*479ab7f0SSascha Wildner {
233*479ab7f0SSascha Wildner 	if (args[0] > 0)
234*479ab7f0SSascha Wildner 		args[0]--;
235*479ab7f0SSascha Wildner 	if (args[1] > 0)
236*479ab7f0SSascha Wildner 		args[1]--;
237*479ab7f0SSascha Wildner 	curs_move(&curx, &cury, args[1], args[0]);
238*479ab7f0SSascha Wildner 	end_term();
239*479ab7f0SSascha Wildner }
240*479ab7f0SSascha Wildner 
241*479ab7f0SSascha Wildner /* Home cursor (left top corner), also called from mode command. */
242*479ab7f0SSascha Wildner void
HO(void)243*479ab7f0SSascha Wildner HO(void)
244*479ab7f0SSascha Wildner {
245*479ab7f0SSascha Wildner 	argc = 1;
246*479ab7f0SSascha Wildner 	args[0] = args[1] = 1;
247*479ab7f0SSascha Wildner 	CM();
248*479ab7f0SSascha Wildner }
249*479ab7f0SSascha Wildner 
250*479ab7f0SSascha Wildner /* Clear line from current position to end of line */
251*479ab7f0SSascha Wildner static void
CL(int direction)252*479ab7f0SSascha Wildner CL(int direction)
253*479ab7f0SSascha Wildner {
254*479ab7f0SSascha Wildner 	int i, len;
255*479ab7f0SSascha Wildner 	UINTN x, y;
256*479ab7f0SSascha Wildner 	CHAR16 *line;
257*479ab7f0SSascha Wildner 
258*479ab7f0SSascha Wildner 	conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
259*479ab7f0SSascha Wildner 	switch (direction) {
260*479ab7f0SSascha Wildner 	case 0:         /* from cursor to end */
261*479ab7f0SSascha Wildner 		len = x - curx + 1;
262*479ab7f0SSascha Wildner 		break;
263*479ab7f0SSascha Wildner 	case 1:         /* from beginning to cursor */
264*479ab7f0SSascha Wildner 		len = curx;
265*479ab7f0SSascha Wildner 		break;
266*479ab7f0SSascha Wildner 	case 2:         /* entire line */
267*479ab7f0SSascha Wildner 		len = x;
268*479ab7f0SSascha Wildner 		break;
269*479ab7f0SSascha Wildner 	}
270*479ab7f0SSascha Wildner 
271*479ab7f0SSascha Wildner 	if (cury == y - 1)
272*479ab7f0SSascha Wildner 		len--;
273*479ab7f0SSascha Wildner 
274*479ab7f0SSascha Wildner 	line = malloc(len * sizeof (CHAR16));
275*479ab7f0SSascha Wildner 	if (line == NULL) {
276*479ab7f0SSascha Wildner 		printf("out of memory\n");
277*479ab7f0SSascha Wildner 		return;
278*479ab7f0SSascha Wildner 	}
279*479ab7f0SSascha Wildner 	for (i = 0; i < len; i++)
280*479ab7f0SSascha Wildner 		line[i] = ' ';
281*479ab7f0SSascha Wildner 	line[len-1] = 0;
282*479ab7f0SSascha Wildner 
283*479ab7f0SSascha Wildner 	if (direction != 0)
284*479ab7f0SSascha Wildner 		curs_move(NULL, NULL, 0, cury);
285*479ab7f0SSascha Wildner 
286*479ab7f0SSascha Wildner 	conout->OutputString(conout, line);
287*479ab7f0SSascha Wildner 	/* restore cursor position */
288*479ab7f0SSascha Wildner 	curs_move(NULL, NULL, curx, cury);
289*479ab7f0SSascha Wildner 	free(line);
290*479ab7f0SSascha Wildner 	end_term();
291*479ab7f0SSascha Wildner }
292*479ab7f0SSascha Wildner 
293*479ab7f0SSascha Wildner static void
get_arg(int c)294*479ab7f0SSascha Wildner get_arg(int c)
295*479ab7f0SSascha Wildner {
296*479ab7f0SSascha Wildner 	if (argc < 0)
297*479ab7f0SSascha Wildner 		argc = 0;
298*479ab7f0SSascha Wildner 	args[argc] *= 10;
299*479ab7f0SSascha Wildner 	args[argc] += c - '0';
300*479ab7f0SSascha Wildner }
301*479ab7f0SSascha Wildner 
302*479ab7f0SSascha Wildner /* Emulate basic capabilities of cons25 terminal */
303*479ab7f0SSascha Wildner static void
efi_term_emu(int c)304*479ab7f0SSascha Wildner efi_term_emu(int c)
305*479ab7f0SSascha Wildner {
306*479ab7f0SSascha Wildner 	static int ansi_col[] = {
307*479ab7f0SSascha Wildner 		0, 4, 2, 6, 1, 5, 3, 7
308*479ab7f0SSascha Wildner 	};
309*479ab7f0SSascha Wildner 	int t, i;
310*479ab7f0SSascha Wildner 
311*479ab7f0SSascha Wildner 	switch (esc) {
312*479ab7f0SSascha Wildner 	case 0:
313*479ab7f0SSascha Wildner 		switch (c) {
314*479ab7f0SSascha Wildner 		case '\033':
315*479ab7f0SSascha Wildner 			esc = c;
316*479ab7f0SSascha Wildner 			break;
317*479ab7f0SSascha Wildner 		default:
318*479ab7f0SSascha Wildner 			efi_cons_rawputchar(c);
319*479ab7f0SSascha Wildner 			break;
320*479ab7f0SSascha Wildner 		}
321*479ab7f0SSascha Wildner 		break;
322*479ab7f0SSascha Wildner 	case '\033':
323*479ab7f0SSascha Wildner 		switch (c) {
324*479ab7f0SSascha Wildner 		case '[':
325*479ab7f0SSascha Wildner 			esc = c;
326*479ab7f0SSascha Wildner 			args[0] = 0;
327*479ab7f0SSascha Wildner 			argc = -1;
328*479ab7f0SSascha Wildner 			break;
329*479ab7f0SSascha Wildner 		default:
330*479ab7f0SSascha Wildner 			bail_out(c);
331*479ab7f0SSascha Wildner 			break;
332*479ab7f0SSascha Wildner 		}
333*479ab7f0SSascha Wildner 		break;
334*479ab7f0SSascha Wildner 	case '[':
335*479ab7f0SSascha Wildner 		switch (c) {
336*479ab7f0SSascha Wildner 		case ';':
337*479ab7f0SSascha Wildner 			if (argc < 0)
338*479ab7f0SSascha Wildner 				argc = 0;
339*479ab7f0SSascha Wildner 			else if (argc + 1 >= MAXARGS)
340*479ab7f0SSascha Wildner 				bail_out(c);
341*479ab7f0SSascha Wildner 			else
342*479ab7f0SSascha Wildner 				args[++argc] = 0;
343*479ab7f0SSascha Wildner 			break;
344*479ab7f0SSascha Wildner 		case 'H':               /* ho = \E[H */
345*479ab7f0SSascha Wildner 			if (argc < 0)
346*479ab7f0SSascha Wildner 				HO();
347*479ab7f0SSascha Wildner 			else if (argc == 1)
348*479ab7f0SSascha Wildner 				CM();
349*479ab7f0SSascha Wildner 			else
350*479ab7f0SSascha Wildner 				bail_out(c);
351*479ab7f0SSascha Wildner 			break;
352*479ab7f0SSascha Wildner 		case 'J':               /* cd = \E[J */
353*479ab7f0SSascha Wildner 			if (argc < 0)
354*479ab7f0SSascha Wildner 				CD();
355*479ab7f0SSascha Wildner 			else
356*479ab7f0SSascha Wildner 				bail_out(c);
357*479ab7f0SSascha Wildner 			break;
358*479ab7f0SSascha Wildner 		case 'm':
359*479ab7f0SSascha Wildner 			if (argc < 0) {
360*479ab7f0SSascha Wildner 				fg_c = DEFAULT_FGCOLOR;
361*479ab7f0SSascha Wildner 				bg_c = DEFAULT_BGCOLOR;
362*479ab7f0SSascha Wildner 			}
363*479ab7f0SSascha Wildner 			for (i = 0; i <= argc; ++i) {
364*479ab7f0SSascha Wildner 				switch (args[i]) {
365*479ab7f0SSascha Wildner 				case 0:         /* back to normal */
366*479ab7f0SSascha Wildner 					fg_c = DEFAULT_FGCOLOR;
367*479ab7f0SSascha Wildner 					bg_c = DEFAULT_BGCOLOR;
368*479ab7f0SSascha Wildner 					break;
369*479ab7f0SSascha Wildner 				case 1:         /* bold */
370*479ab7f0SSascha Wildner 					fg_c |= 0x8;
371*479ab7f0SSascha Wildner 					break;
372*479ab7f0SSascha Wildner 				case 4:         /* underline */
373*479ab7f0SSascha Wildner 				case 5:         /* blink */
374*479ab7f0SSascha Wildner 					bg_c |= 0x8;
375*479ab7f0SSascha Wildner 					break;
376*479ab7f0SSascha Wildner 				case 7:         /* reverse */
377*479ab7f0SSascha Wildner 					t = fg_c;
378*479ab7f0SSascha Wildner 					fg_c = bg_c;
379*479ab7f0SSascha Wildner 					bg_c = t;
380*479ab7f0SSascha Wildner 					break;
381*479ab7f0SSascha Wildner 				case 30: case 31: case 32: case 33:
382*479ab7f0SSascha Wildner 				case 34: case 35: case 36: case 37:
383*479ab7f0SSascha Wildner 					fg_c = ansi_col[args[i] - 30];
384*479ab7f0SSascha Wildner 					break;
385*479ab7f0SSascha Wildner 				case 39:        /* normal */
386*479ab7f0SSascha Wildner 					fg_c = DEFAULT_FGCOLOR;
387*479ab7f0SSascha Wildner 					break;
388*479ab7f0SSascha Wildner 				case 40: case 41: case 42: case 43:
389*479ab7f0SSascha Wildner 				case 44: case 45: case 46: case 47:
390*479ab7f0SSascha Wildner 					bg_c = ansi_col[args[i] - 40];
391*479ab7f0SSascha Wildner 					break;
392*479ab7f0SSascha Wildner 				case 49:        /* normal */
393*479ab7f0SSascha Wildner 					bg_c = DEFAULT_BGCOLOR;
394*479ab7f0SSascha Wildner 					break;
395*479ab7f0SSascha Wildner 				}
396*479ab7f0SSascha Wildner 			}
397*479ab7f0SSascha Wildner 			conout->SetAttribute(conout, EFI_TEXT_ATTR(fg_c, bg_c));
398*479ab7f0SSascha Wildner 			end_term();
399*479ab7f0SSascha Wildner 			break;
400*479ab7f0SSascha Wildner 		default:
401*479ab7f0SSascha Wildner 			if (isdigit(c))
402*479ab7f0SSascha Wildner 				get_arg(c);
403*479ab7f0SSascha Wildner 			else
404*479ab7f0SSascha Wildner 				bail_out(c);
405*479ab7f0SSascha Wildner 			break;
406*479ab7f0SSascha Wildner 		}
407*479ab7f0SSascha Wildner 		break;
408*479ab7f0SSascha Wildner 	default:
409*479ab7f0SSascha Wildner 		bail_out(c);
410*479ab7f0SSascha Wildner 		break;
411*479ab7f0SSascha Wildner 	}
412*479ab7f0SSascha Wildner }
413*479ab7f0SSascha Wildner 
414*479ab7f0SSascha Wildner void
efi_cons_putchar(int c)415*479ab7f0SSascha Wildner efi_cons_putchar(int c)
416*479ab7f0SSascha Wildner {
417*479ab7f0SSascha Wildner #ifdef TERM_EMU
418*479ab7f0SSascha Wildner 	efi_term_emu(c);
419*479ab7f0SSascha Wildner #else
420*479ab7f0SSascha Wildner 	efi_cons_rawputchar(c);
421*479ab7f0SSascha Wildner #endif
422*479ab7f0SSascha Wildner }
423*479ab7f0SSascha Wildner 
424*479ab7f0SSascha Wildner int
efi_cons_getchar(void)425*479ab7f0SSascha Wildner efi_cons_getchar(void)
426*479ab7f0SSascha Wildner {
427*479ab7f0SSascha Wildner 	EFI_INPUT_KEY key;
428*479ab7f0SSascha Wildner 	EFI_STATUS status;
429*479ab7f0SSascha Wildner 	UINTN junk;
430*479ab7f0SSascha Wildner 
431*479ab7f0SSascha Wildner again:
432*479ab7f0SSascha Wildner 	/* Try to read a key stroke. We wait for one if none is pending. */
433*479ab7f0SSascha Wildner 	status = conin->ReadKeyStroke(conin, &key);
434*479ab7f0SSascha Wildner 	if (status == EFI_NOT_READY) {
435*479ab7f0SSascha Wildner 		BS->WaitForEvent(1, &conin->WaitForKey, &junk);
436*479ab7f0SSascha Wildner 		goto again;
437*479ab7f0SSascha Wildner 	}
438*479ab7f0SSascha Wildner 	switch (key.ScanCode) {
439*479ab7f0SSascha Wildner 	case 0x17: /* ESC */
440*479ab7f0SSascha Wildner 		return (0x1b);  /* esc */
441*479ab7f0SSascha Wildner 	}
442*479ab7f0SSascha Wildner 
443*479ab7f0SSascha Wildner 	/* this can return  */
444*479ab7f0SSascha Wildner 	return (key.UnicodeChar);
445*479ab7f0SSascha Wildner }
446*479ab7f0SSascha Wildner 
447*479ab7f0SSascha Wildner int
efi_cons_poll(void)448*479ab7f0SSascha Wildner efi_cons_poll(void)
449*479ab7f0SSascha Wildner {
450*479ab7f0SSascha Wildner 	/* This can clear the signaled state. */
451*479ab7f0SSascha Wildner 	return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
452*479ab7f0SSascha Wildner }
453*479ab7f0SSascha Wildner 
454*479ab7f0SSascha Wildner /* Plain direct access to EFI OutputString(). */
455*479ab7f0SSascha Wildner void
efi_cons_efiputchar(int c)456*479ab7f0SSascha Wildner efi_cons_efiputchar(int c)
457*479ab7f0SSascha Wildner {
458*479ab7f0SSascha Wildner 	CHAR16 buf[2];
459*479ab7f0SSascha Wildner 
460*479ab7f0SSascha Wildner 	/*
461*479ab7f0SSascha Wildner 	 * translate box chars to unicode
462*479ab7f0SSascha Wildner 	 */
463*479ab7f0SSascha Wildner 	switch (c) {
464*479ab7f0SSascha Wildner 	/* single frame */
465*479ab7f0SSascha Wildner 	case 0xb3: buf[0] = BOXDRAW_VERTICAL; break;
466*479ab7f0SSascha Wildner 	case 0xbf: buf[0] = BOXDRAW_DOWN_LEFT; break;
467*479ab7f0SSascha Wildner 	case 0xc0: buf[0] = BOXDRAW_UP_RIGHT; break;
468*479ab7f0SSascha Wildner 	case 0xc4: buf[0] = BOXDRAW_HORIZONTAL; break;
469*479ab7f0SSascha Wildner 	case 0xda: buf[0] = BOXDRAW_DOWN_RIGHT; break;
470*479ab7f0SSascha Wildner 	case 0xd9: buf[0] = BOXDRAW_UP_LEFT; break;
471*479ab7f0SSascha Wildner 
472*479ab7f0SSascha Wildner 	/* double frame */
473*479ab7f0SSascha Wildner 	case 0xba: buf[0] = BOXDRAW_DOUBLE_VERTICAL; break;
474*479ab7f0SSascha Wildner 	case 0xbb: buf[0] = BOXDRAW_DOUBLE_DOWN_LEFT; break;
475*479ab7f0SSascha Wildner 	case 0xbc: buf[0] = BOXDRAW_DOUBLE_UP_LEFT; break;
476*479ab7f0SSascha Wildner 	case 0xc8: buf[0] = BOXDRAW_DOUBLE_UP_RIGHT; break;
477*479ab7f0SSascha Wildner 	case 0xc9: buf[0] = BOXDRAW_DOUBLE_DOWN_RIGHT; break;
478*479ab7f0SSascha Wildner 	case 0xcd: buf[0] = BOXDRAW_DOUBLE_HORIZONTAL; break;
479*479ab7f0SSascha Wildner 
480*479ab7f0SSascha Wildner 	default:
481*479ab7f0SSascha Wildner 		buf[0] = c;
482*479ab7f0SSascha Wildner 	}
483*479ab7f0SSascha Wildner         buf[1] = 0;     /* terminate string */
484*479ab7f0SSascha Wildner 
485*479ab7f0SSascha Wildner 	conout->OutputString(conout, buf);
486*479ab7f0SSascha Wildner }
487