bootloader console: encode output
EFI wants UCS-2, BIOS uses CP437. Other systems untouched.
As a side effect, the high bits don't spill anymore into other fields.
Fixes: #18016
Change-Id: I704e8b8ab5e2c0d07ebbe033b3313245252ffd5d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9976
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Diff
src/system/boot/platform/bios_ia32/Jamfile | 1 +
src/system/boot/platform/bios_ia32/console.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
src/system/boot/platform/efi/Jamfile | 1 +
src/system/boot/platform/efi/console.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++-
src/system/boot/platform/pxe_ia32/Jamfile | 1 +
5 files changed, 87 insertions(+), 9 deletions(-)
@@ -5,6 +5,7 @@
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders [ FDirName graphics common ] ;
UsePrivateHeaders [ FDirName graphics vesa ] ;
UsePrivateHeaders [ FDirName interface ] ;
UsePrivateHeaders [ FDirName storage ] ;
{
@@ -10,8 +10,10 @@
#include "video.h"
#include <SupportDefs.h>
#include <util/kernel_cpp.h>
#include <boot/stage2.h>
#include <utf8_functions.h>
#include <util/kernel_cpp.h>
#include <string.h>
@@ -80,16 +82,51 @@
if (gKernelArgs.frame_buffer.enabled)
return bufferSize;
for (uint32 i = 0; i < bufferSize; i++) {
if (string[0] == '\n')
size_t length = bufferSize;
while (length > 0) {
if (string[0] == '\n') {
sScreenOffset += sScreenWidth - (sScreenOffset % sScreenWidth);
else
length--;
string++;
} else if ((string[0] & 0x80) == 0) {
sScreenBase[sScreenOffset++] = sColor | string[0];
length--;
string++;
} else {
uint32 codepoint;
uint32 charLen = UTF8NextCharLen(string, length);
if (charLen > 0) {
codepoint = UTF8ToCharCode(&string);
length -= charLen;
} else {
codepoint = 0xfffd;
string++;
length--;
}
switch (codepoint) {
case 0x25B2:
sScreenBase[sScreenOffset++] = sColor | 0x1e;
break;
case 0x25BC:
sScreenBase[sScreenOffset++] = sColor | 0x1f;
break;
case 0x2026:
WriteAt(cookie, -1, "...", 3);
break;
case 0x00A9:
WriteAt(cookie, -1, "(C)", 3);
break;
default:
sScreenBase[sScreenOffset++] = sColor | '?';
}
}
if (sScreenOffset >= sScreenWidth * sScreenHeight)
scroll_up();
string++;
}
return bufferSize;
}
@@ -1,6 +1,7 @@
SubDir HAIKU_TOP src system boot platform efi ;
UsePrivateHeaders [ FDirName graphics common ] ;
UsePrivateHeaders [ FDirName interface ] ;
UsePrivateHeaders [ FDirName kernel boot ] ;
UsePrivateHeaders [ FDirName kernel platform ] ;
UsePrivateHeaders [ FDirName kernel boot platform efi ] ;
@@ -16,6 +16,7 @@
#include <boot/platform.h>
#include <boot/platform/generic/video.h>
#include <efi/protocol/console-control.h>
#include <utf8_functions.h>
#include <util/kernel_cpp.h>
#include "efi_platform.h"
@@ -82,8 +83,45 @@
char16_t ucsBuffer[bufferSize + 3];
uint32 j = 0;
for (uint32 i = 0; i < bufferSize; i++) {
switch (string[i]) {
size_t length = bufferSize;
while (length > 0) {
uint32 codepoint;
if (string[0] == 0) {
codepoint = 0;
string++;
length--;
} else {
uint32 charLen = UTF8NextCharLen(string, length);
if (charLen > 0) {
codepoint = UTF8ToCharCode(&string);
length -= charLen;
} else {
codepoint = 0xfffd;
string++;
length--;
}
}
if (codepoint > 0xffff) {
codepoint = 0xfffd;
} else if (codepoint < 0x20) {
static const uint16 controlCodes[] = {
0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
0x0008, 0x0009, 0x000A, 0x2642, 0x2640, 0x000D, 0x266B, 0x263C,
0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC
};
codepoint = controlCodes[codepoint];
}
switch (codepoint) {
case '\n': {
ucsBuffer[j++] = '\r';
ucsBuffer[j++] = '\n';
@@ -98,7 +136,7 @@
continue;
}
default:
ucsBuffer[j++] = (char16_t)string[i];
ucsBuffer[j++] = codepoint;
}
}
@@ -7,6 +7,7 @@
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
UsePrivateHeaders [ FDirName graphics common ] ;
UsePrivateHeaders [ FDirName graphics vesa ] ;
UsePrivateHeaders [ FDirName interface ] ;
UsePrivateHeaders [ FDirName storage ] ;
{