efi_console.c revision 199767f8919635c4928607450d9e0abb932109ce
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
__FBSDID("$FreeBSD$");
#include <efi.h>
#include <efilib.h>
#include "bootstrap.h"
static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
static SIMPLE_INPUT_INTERFACE *conin;
#ifdef TERM_EMU
#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
#define DEFAULT_BGCOLOR EFI_BLACK
#define MAXARGS 8
#define KEYBUFSZ 10
static int esc;
static void CL(int);
void HO(void);
void end_term(void);
#endif
static void efi_cons_probe(struct console *);
static int efi_cons_init(struct console *, int);
void efi_cons_putchar(struct console *, int);
int efi_cons_getchar(struct console *);
void efi_cons_efiputchar(int);
int efi_cons_poll(struct console *);
struct console efi_console = {
"text",
"EFI console",
0,
0
};
#ifdef TERM_EMU
/* Get cursor position. */
void
{
}
/* Move cursor to x rows and y cols (0-based). */
void
{
}
/* Clear internal state of the terminal emulation code. */
void
end_term(void)
{
esc = 0;
argc = -1;
}
#endif
static void
{
}
static int
{
#ifdef TERM_EMU
end_term();
#endif
return 0;
}
static void
efi_cons_rawputchar(int c)
{
int i;
UINTN x, y;
static int ignorenl = 0;
if (c == '\t')
/* XXX lame tab expansion */
for (i = 0; i < 8; i++)
efi_cons_rawputchar(' ');
else {
#ifndef TERM_EMU
if (c == '\n')
efi_cons_efiputchar('\r');
else
#else
switch (c) {
case '\r':
curx = 0;
break;
case '\n':
if (ignorenl)
ignorenl = 0;
else
cury++;
curx = 0;
if (cury >= y) {
efi_cons_efiputchar('\n');
cury--;
}
break;
case '\b':
if (curx > 0)
curx--;
break;
default:
if (curx > x) {
curx = 0;
cury++;
}
if (cury > y-1) {
curx = 0;
efi_cons_efiputchar('\n');
cury--;
}
}
curx++;
if (curx == x) {
curx = 0;
ignorenl = 1;
}
} else if (curx == x) {
curx = 0;
if (cury == y)
efi_cons_efiputchar('\n');
else
cury++;
}
}
#endif
}
}
/* Gracefully exit ESC-sequence processing in case of misunderstanding. */
static void
bail_out(int c)
{
int i;
if (esc) {
efi_cons_rawputchar('\033');
if (esc != '\033')
for (i = 0; i <= argc; ++i) {
while (*ch)
efi_cons_rawputchar(*ch++);
}
}
end_term();
}
/* Clear display from current position to end of screen. */
static void
CD(void) {
UINTN i, x, y;
end_term();
return;
}
CL(0); /* clear current line from cursor to end */
CL(0);
}
end_term();
}
/*
* Absolute cursor move to args[0] rows and args[1] columns
* (the coordinates are 1-based).
*/
static void
CM(void)
{
if (args[0] > 0)
args[0]--;
if (args[1] > 0)
args[1]--;
end_term();
}
/* Home cursor (left top corner), also called from mode command. */
void
HO(void)
{
argc = 1;
CM();
}
/* Clear line from current position to end of line */
static void
{
int i, len;
UINTN x, y;
switch (direction) {
case 0: /* from cursor to end */
break;
case 1: /* from beginning to cursor */
break;
case 2: /* entire line */
default:
len = x;
break;
}
if (cury == y - 1)
len--;
printf("out of memory\n");
return;
}
for (i = 0; i < len; i++)
line[i] = ' ';
if (direction != 0)
/* restore cursor position */
end_term();
}
static void
get_arg(int c)
{
if (argc < 0)
argc = 0;
}
/* Emulate basic capabilities of sun-color terminal */
static void
efi_term_emu(int c)
{
static int ansi_col[] = {
0, 4, 2, 6, 1, 5, 3, 7
};
int t, i;
switch (esc) {
case 0:
switch (c) {
case '\033':
esc = c;
break;
default:
break;
}
break;
case '\033':
switch (c) {
case '[':
esc = c;
args[0] = 0;
argc = -1;
break;
default:
bail_out(c);
break;
}
break;
case '[':
switch (c) {
case ';':
if (argc < 0)
argc = 0;
bail_out(c);
else
break;
case 'A': /* UP = \E[%dA */
if (argc == 0) {
UINTN x, y;
get_pos(&x, &y);
CM();
} else
bail_out(c);
break;
case 'B': /* DO = \E[%dB */
if (argc == 0) {
UINTN x, y;
get_pos(&x, &y);
CM();
} else
bail_out(c);
break;
case 'C': /* RI = \E[%dC */
if (argc == 0) {
UINTN x, y;
get_pos(&x, &y);
args[0] = y + 1;
CM();
} else
bail_out(c);
break;
case 'H': /* ho = \E[H */
if (argc < 0)
HO();
else if (argc == 1)
CM();
else
bail_out(c);
break;
case 'J': /* cd = \E[J */
if (argc < 0)
CD();
else
bail_out(c);
break;
case 'K':
if (argc < 0)
CL(0);
else if (argc == 0)
switch (args[0]) {
case 0:
case 1:
case 2:
break;
default:
bail_out(c);
}
else
bail_out(c);
break;
case 'm':
if (argc < 0) {
}
for (i = 0; i <= argc; ++i) {
switch (args[i]) {
case 0: /* back to normal */
break;
case 1: /* bold */
fg_c |= 0x8;
break;
case 4: /* underline */
case 5: /* blink */
bg_c |= 0x8;
break;
case 7: /* reverse */
t = fg_c;
bg_c = t;
break;
case 30: case 31: case 32: case 33:
case 34: case 35: case 36: case 37:
break;
case 39: /* normal */
break;
case 40: case 41: case 42: case 43:
case 44: case 45: case 46: case 47:
break;
case 49: /* normal */
break;
}
}
end_term();
break;
default:
if (isdigit(c))
get_arg(c);
else
bail_out(c);
break;
}
break;
default:
bail_out(c);
break;
}
}
void
{
#ifdef TERM_EMU
efi_term_emu(c);
#else
#endif
}
int
{
int i, c;
for (i = 0; i < KEYBUFSZ; i++) {
if (keybuf[i] != 0) {
c = keybuf[i];
keybuf[i] = 0;
return (c);
}
}
/* Try to read a key stroke. We wait for one if none is pending. */
if (status == EFI_NOT_READY) {
}
case 0x1: /* UP */
keybuf[0] = '[';
return (0x1b); /* esc */
case 0x2: /* DOWN */
keybuf[0] = '[';
return (0x1b); /* esc */
case 0x3: /* RIGHT */
keybuf[0] = '[';
return (0x1b); /* esc */
case 0x4: /* LEFT */
keybuf[0] = '[';
return (0x1b); /* esc */
case 0x17: /* ESC */
return (0x1b); /* esc */
}
/* this can return */
return (key.UnicodeChar);
}
int
{
int i;
for (i = 0; i < KEYBUFSZ; i++) {
if (keybuf[i] != 0)
return (1);
}
/* This can clear the signaled state. */
}
/* Plain direct access to EFI OutputString(). */
void
efi_cons_efiputchar(int c)
{
/*
* translate box chars to unicode
*/
switch (c) {
/* single frame */
/* double frame */
default:
buf[0] = c;
}
}