svn commit: r353992 - stable/12/stand/efi/libefi
Kyle Evans
kevans at FreeBSD.org
Thu Oct 24 03:24:29 UTC 2019
Author: kevans
Date: Thu Oct 24 03:24:28 2019
New Revision: 353992
URL: https://svnweb.freebsd.org/changeset/base/353992
Log:
MFC r351695-r351696
r351695:
loader.efi: some systems do not translate scan code 0x8 to backspace
Add scancode translation for backspace.
r351696:
loader.efi: use and prefer coninex interface
Add support for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
Modified:
stable/12/stand/efi/libefi/efi_console.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/stand/efi/libefi/efi_console.c
==============================================================================
--- stable/12/stand/efi/libefi/efi_console.c Thu Oct 24 03:21:30 2019 (r353991)
+++ stable/12/stand/efi/libefi/efi_console.c Thu Oct 24 03:24:28 2019 (r353992)
@@ -32,8 +32,10 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h"
+static EFI_GUID simple_input_ex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
static SIMPLE_INPUT_INTERFACE *conin;
+static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *coninex;
#ifdef TERM_EMU
#define DEFAULT_FGCOLOR EFI_LIGHTGRAY
@@ -115,6 +117,8 @@ efi_cons_probe(struct console *cp)
static int
efi_cons_init(int arg)
{
+ EFI_STATUS status;
+
#ifdef TERM_EMU
conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
DEFAULT_BGCOLOR));
@@ -125,7 +129,11 @@ efi_cons_init(int arg)
bg_c = DEFAULT_BGCOLOR;
#endif
conout->EnableCursor(conout, TRUE);
- return 0;
+ status = BS->OpenProtocol(ST->ConsoleInHandle, &simple_input_ex_guid,
+ (void **)&coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (status != EFI_SUCCESS)
+ coninex = NULL;
+ return (0);
}
static void
@@ -478,27 +486,30 @@ keybuf_inschar(EFI_INPUT_KEY *key)
{
switch (key->ScanCode) {
- case 0x1: /* UP */
+ case SCAN_UP: /* UP */
keybuf[0] = 0x1b; /* esc */
keybuf[1] = '[';
keybuf[2] = 'A';
break;
- case 0x2: /* DOWN */
+ case SCAN_DOWN: /* DOWN */
keybuf[0] = 0x1b; /* esc */
keybuf[1] = '[';
keybuf[2] = 'B';
break;
- case 0x3: /* RIGHT */
+ case SCAN_RIGHT: /* RIGHT */
keybuf[0] = 0x1b; /* esc */
keybuf[1] = '[';
keybuf[2] = 'C';
break;
- case 0x4: /* LEFT */
+ case SCAN_LEFT: /* LEFT */
keybuf[0] = 0x1b; /* esc */
keybuf[1] = '[';
keybuf[2] = 'D';
break;
- case 0x17:
+ case SCAN_DELETE:
+ keybuf[0] = CHAR_BACKSPACE;
+ break;
+ case SCAN_ESC:
keybuf[0] = 0x1b; /* esc */
break;
default:
@@ -521,6 +532,40 @@ efi_readkey(void)
return (false);
}
+static bool
+efi_readkey_ex(void)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY *kp;
+ EFI_KEY_DATA key_data;
+ uint32_t kss;
+
+ status = coninex->ReadKeyStrokeEx(coninex, &key_data);
+ if (status == EFI_SUCCESS) {
+ kss = key_data.KeyState.KeyShiftState;
+ kp = &key_data.Key;
+ if (kss & EFI_SHIFT_STATE_VALID) {
+
+ /*
+ * quick mapping to control chars, replace with
+ * map lookup later.
+ */
+ if (kss & EFI_RIGHT_CONTROL_PRESSED ||
+ kss & EFI_LEFT_CONTROL_PRESSED) {
+ if (kp->UnicodeChar >= 'a' &&
+ kp->UnicodeChar <= 'z') {
+ kp->UnicodeChar -= 'a';
+ kp->UnicodeChar++;
+ }
+ }
+ }
+
+ keybuf_inschar(kp);
+ return (true);
+ }
+ return (false);
+}
+
int
efi_cons_getchar(void)
{
@@ -531,8 +576,13 @@ efi_cons_getchar(void)
key_pending = 0;
- if (efi_readkey())
- return (keybuf_getchar());
+ if (coninex == NULL) {
+ if (efi_readkey())
+ return (keybuf_getchar());
+ } else {
+ if (efi_readkey_ex())
+ return (keybuf_getchar());
+ }
return (-1);
}
@@ -540,6 +590,7 @@ efi_cons_getchar(void)
int
efi_cons_poll(void)
{
+ EFI_STATUS status;
if (keybuf_ischar() || key_pending)
return (1);
@@ -549,10 +600,21 @@ efi_cons_poll(void)
* WaitForKey().
* CheckEvent() can clear the signaled state.
*/
- if (conin->WaitForKey == NULL)
- key_pending = efi_readkey();
- else
- key_pending = BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS;
+ if (coninex != NULL) {
+ if (coninex->WaitForKeyEx == NULL) {
+ key_pending = efi_readkey_ex();
+ } else {
+ status = BS->CheckEvent(coninex->WaitForKeyEx);
+ key_pending = status == EFI_SUCCESS;
+ }
+ } else {
+ if (conin->WaitForKey == NULL) {
+ key_pending = efi_readkey();
+ } else {
+ status = BS->CheckEvent(conin->WaitForKey);
+ key_pending = status == EFI_SUCCESS;
+ }
+ }
return (key_pending);
}
More information about the svn-src-all
mailing list