openfirmware: Refactor console implementation following bootloader changes.
Confirmed working on sparc Change-Id: I60bf82978ccf967e7e10611f6360cadccf22d15d Reviewed-on: https://review.haiku-os.org/c/haiku/+/4667 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
9aba9395e7
commit
7d41530f62
@@ -9,9 +9,7 @@
|
|||||||
#include <boot/vfs.h>
|
#include <boot/vfs.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
class Handle : public Node {
|
||||||
|
|
||||||
class Handle : public ConsoleNode {
|
|
||||||
public:
|
public:
|
||||||
Handle(intptr_t handle, bool takeOwnership = true);
|
Handle(intptr_t handle, bool takeOwnership = true);
|
||||||
Handle();
|
Handle();
|
||||||
@@ -29,6 +27,4 @@ class Handle : public ConsoleNode {
|
|||||||
bool fOwnHandle;
|
bool fOwnHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
#endif /* HANDLE_H */
|
#endif /* HANDLE_H */
|
||||||
|
|||||||
@@ -18,59 +18,86 @@
|
|||||||
#include "Handle.h"
|
#include "Handle.h"
|
||||||
|
|
||||||
|
|
||||||
class ConsoleHandle : public Handle {
|
class Console : public ConsoleNode {
|
||||||
public:
|
public:
|
||||||
ConsoleHandle();
|
Console();
|
||||||
|
|
||||||
|
void SetHandles(intptr_t readHandle, intptr_t writeHandle, bool takeOwnership = true);
|
||||||
|
|
||||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
||||||
size_t bufferSize);
|
size_t bufferSize);
|
||||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
|
||||||
size_t bufferSize);
|
size_t bufferSize);
|
||||||
};
|
|
||||||
|
|
||||||
class InputConsoleHandle : public ConsoleHandle {
|
virtual void ClearScreen();
|
||||||
public:
|
virtual int32 Width();
|
||||||
InputConsoleHandle();
|
virtual int32 Height();
|
||||||
|
virtual void SetCursor(int32 x, int32 y);
|
||||||
|
virtual void SetCursorVisible(bool visible);
|
||||||
|
virtual void SetColors(int32 foreground, int32 background);
|
||||||
|
|
||||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer,
|
void PutBackChar(char c);
|
||||||
size_t bufferSize);
|
void PutBackChars(const char *buffer, int count);
|
||||||
|
|
||||||
void PutChar(char c);
|
|
||||||
void PutChars(const char *buffer, int count);
|
|
||||||
char GetChar();
|
char GetChar();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum { BUFFER_SIZE = 32 };
|
Handle fReadHandle, fWriteHandle;
|
||||||
|
|
||||||
char fBuffer[BUFFER_SIZE];
|
enum { BUFFER_SIZE = 32 };
|
||||||
|
char fReadBuffer[BUFFER_SIZE];
|
||||||
int fStart;
|
int fStart;
|
||||||
int fCount;
|
int fCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static InputConsoleHandle sInput;
|
extern ConsoleNode* gConsoleNode;
|
||||||
static ConsoleHandle sOutput;
|
static Console sConsole;
|
||||||
FILE *stdin, *stdout, *stderr;
|
FILE *stdin, *stdout, *stderr;
|
||||||
|
|
||||||
|
|
||||||
ConsoleHandle::ConsoleHandle()
|
Console::Console()
|
||||||
:
|
:
|
||||||
Handle()
|
ConsoleNode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Console::SetHandles(intptr_t readHandle, intptr_t writeHandle, bool takeOwnership)
|
||||||
|
{
|
||||||
|
fReadHandle.SetHandle(readHandle, takeOwnership);
|
||||||
|
fWriteHandle.SetHandle(readHandle, takeOwnership);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
ConsoleHandle::ReadAt(void */*cookie*/, off_t /*pos*/, void *buffer,
|
Console::ReadAt(void */*cookie*/, off_t /*pos*/, void *_buffer,
|
||||||
size_t bufferSize)
|
size_t bufferSize)
|
||||||
{
|
{
|
||||||
// don't seek in character devices
|
char *buffer = (char*)_buffer;
|
||||||
return of_read(fHandle, buffer, bufferSize);
|
|
||||||
|
// copy buffered bytes first
|
||||||
|
int bytesTotal = 0;
|
||||||
|
while (bufferSize > 0 && fCount > 0) {
|
||||||
|
*buffer++ = GetChar();
|
||||||
|
bytesTotal++;
|
||||||
|
bufferSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read from console
|
||||||
|
if (bufferSize > 0) {
|
||||||
|
ssize_t bytesRead = fReadHandle.ReadAt(NULL, -1, buffer, bufferSize);
|
||||||
|
if (bytesRead < 0)
|
||||||
|
return bytesRead;
|
||||||
|
bytesTotal += bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytesTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
|
Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
|
||||||
size_t bufferSize)
|
size_t bufferSize)
|
||||||
{
|
{
|
||||||
const char *string = (const char *)buffer;
|
const char *string = (const char *)buffer;
|
||||||
@@ -96,7 +123,7 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
of_write(fHandle, string, length);
|
fWriteHandle.WriteAt(NULL, -1, string, length);
|
||||||
string += length;
|
string += length;
|
||||||
bufferSize -= length;
|
bufferSize -= length;
|
||||||
}
|
}
|
||||||
@@ -104,7 +131,7 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
|
|||||||
if (newLine) {
|
if (newLine) {
|
||||||
// this code replaces a single '\n' with '\r\n', so it
|
// this code replaces a single '\n' with '\r\n', so it
|
||||||
// bumps the string/bufferSize only a single character
|
// bumps the string/bufferSize only a single character
|
||||||
of_write(fHandle, "\r\n", 2);
|
fWriteHandle.WriteAt(NULL, -1, "\r\n", 2);
|
||||||
string++;
|
string++;
|
||||||
bufferSize--;
|
bufferSize--;
|
||||||
}
|
}
|
||||||
@@ -114,72 +141,34 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
InputConsoleHandle::InputConsoleHandle()
|
|
||||||
:
|
|
||||||
ConsoleHandle(),
|
|
||||||
fStart(0),
|
|
||||||
fCount(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
|
||||||
InputConsoleHandle::ReadAt(void */*cookie*/, off_t /*pos*/, void *_buffer,
|
|
||||||
size_t bufferSize)
|
|
||||||
{
|
|
||||||
char *buffer = (char*)_buffer;
|
|
||||||
|
|
||||||
// copy buffered bytes first
|
|
||||||
int bytesTotal = 0;
|
|
||||||
while (bufferSize > 0 && fCount > 0) {
|
|
||||||
*buffer++ = GetChar();
|
|
||||||
bytesTotal++;
|
|
||||||
bufferSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read from console
|
|
||||||
if (bufferSize > 0) {
|
|
||||||
ssize_t bytesRead = ConsoleHandle::ReadAt(NULL, 0, buffer, bufferSize);
|
|
||||||
if (bytesRead < 0)
|
|
||||||
return bytesRead;
|
|
||||||
bytesTotal += bytesRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytesTotal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InputConsoleHandle::PutChar(char c)
|
Console::PutBackChar(char c)
|
||||||
{
|
{
|
||||||
if (fCount >= BUFFER_SIZE)
|
if (fCount >= BUFFER_SIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int pos = (fStart + fCount) % BUFFER_SIZE;
|
int pos = (fStart + fCount) % BUFFER_SIZE;
|
||||||
fBuffer[pos] = c;
|
fReadBuffer[pos] = c;
|
||||||
fCount++;
|
fCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InputConsoleHandle::PutChars(const char *buffer, int count)
|
Console::PutBackChars(const char *buffer, int count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
PutChar(buffer[i]);
|
PutBackChar(buffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char
|
char
|
||||||
InputConsoleHandle::GetChar()
|
Console::GetChar()
|
||||||
{
|
{
|
||||||
if (fCount == 0)
|
if (fCount == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fCount--;
|
fCount--;
|
||||||
char c = fBuffer[fStart];
|
char c = fReadBuffer[fStart];
|
||||||
fStart = (fStart + 1) % BUFFER_SIZE;
|
fStart = (fStart + 1) % BUFFER_SIZE;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -199,12 +188,12 @@ console_init(void)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sInput.SetHandle(input);
|
sConsole.SetHandles(input, output);
|
||||||
sOutput.SetHandle(output);
|
gConsoleNode = &sConsole;
|
||||||
|
|
||||||
// now that we're initialized, enable stdio functionality
|
// now that we're initialized, enable stdio functionality
|
||||||
stdin = (FILE *)&sInput;
|
stdin = (FILE *)gConsoleNode;
|
||||||
stdout = stderr = (FILE *)&sOutput;
|
stdout = stderr = (FILE *)gConsoleNode;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -214,12 +203,12 @@ console_init(void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
console_clear_screen(void)
|
Console::ClearScreen()
|
||||||
{
|
{
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
// Send both a clear screen (for serial terminal) and a vertical form
|
// Send both a clear screen (for serial terminal) and a vertical form
|
||||||
// feed for on-screen console
|
// feed for on-screen console
|
||||||
sOutput.Write("\014\033[2J", 5);
|
Write("\014\033[2J", 5);
|
||||||
#else
|
#else
|
||||||
of_interpret("erase-screen", 0, 0);
|
of_interpret("erase-screen", 0, 0);
|
||||||
#endif
|
#endif
|
||||||
@@ -227,7 +216,7 @@ console_clear_screen(void)
|
|||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
console_width(void)
|
Console::Width()
|
||||||
{
|
{
|
||||||
intptr_t columnCount;
|
intptr_t columnCount;
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
@@ -241,7 +230,7 @@ console_width(void)
|
|||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
console_height(void)
|
Console::Height()
|
||||||
{
|
{
|
||||||
intptr_t lineCount;
|
intptr_t lineCount;
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
@@ -255,13 +244,13 @@ console_height(void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
console_set_cursor(int32 x, int32 y)
|
Console::SetCursor(int32 x, int32 y)
|
||||||
{
|
{
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
char buffer[11];
|
char buffer[11];
|
||||||
int len = snprintf(buffer, sizeof(buffer),
|
int len = snprintf(buffer, sizeof(buffer),
|
||||||
"\033[%" B_PRId32 ";%" B_PRId32 "H", y, x);
|
"\033[%" B_PRId32 ";%" B_PRId32 "H", y, x);
|
||||||
sOutput.Write(buffer, len);
|
Write(buffer, len);
|
||||||
#else
|
#else
|
||||||
// Note: We toggle the cursor temporarily to prevent a cursor artifact at
|
// Note: We toggle the cursor temporarily to prevent a cursor artifact at
|
||||||
// at the old location.
|
// at the old location.
|
||||||
@@ -275,13 +264,7 @@ console_set_cursor(int32 x, int32 y)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
console_show_cursor(void)
|
Console::SetCursorVisible(bool visible)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
console_hide_cursor(void)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,14 +300,14 @@ translate_color(int32 color)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
console_set_color(int32 foreground, int32 background)
|
Console::SetColors(int32 foreground, int32 background)
|
||||||
{
|
{
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
// Sadly it seems we can only get inverse video, nothing else seems to work
|
// Sadly it seems we can only get inverse video, nothing else seems to work
|
||||||
if (background != 0)
|
if (background != 0)
|
||||||
sOutput.Write("\033[7m", 4);
|
Write("\033[7m", 4);
|
||||||
else
|
else
|
||||||
sOutput.Write("\033[0m", 4);
|
Write("\033[0m", 4);
|
||||||
#else
|
#else
|
||||||
// Note: Toggling the cursor doesn't seem to help. We still get cursor
|
// Note: Toggling the cursor doesn't seem to help. We still get cursor
|
||||||
// artifacts.
|
// artifacts.
|
||||||
@@ -369,7 +352,7 @@ console_wait_for_key(void)
|
|||||||
char buffer[3];
|
char buffer[3];
|
||||||
ssize_t bytesRead;
|
ssize_t bytesRead;
|
||||||
do {
|
do {
|
||||||
bytesRead = sInput.ReadAt(NULL, 0, buffer, 3);
|
bytesRead = sConsole.ReadAt(NULL, 0, buffer, 3);
|
||||||
if (bytesRead < 0)
|
if (bytesRead < 0)
|
||||||
return 0;
|
return 0;
|
||||||
} while (bytesRead == 0);
|
} while (bytesRead == 0);
|
||||||
@@ -383,7 +366,7 @@ console_wait_for_key(void)
|
|||||||
|
|
||||||
// put back unread chars
|
// put back unread chars
|
||||||
if (bytesRead > 1)
|
if (bytesRead > 1)
|
||||||
sInput.PutChars(buffer + 1, bytesRead - 1);
|
sConsole.PutBackChars(buffer + 1, bytesRead - 1);
|
||||||
|
|
||||||
return buffer[0];
|
return buffer[0];
|
||||||
}
|
}
|
||||||
@@ -393,7 +376,7 @@ int
|
|||||||
console_check_for_key(void)
|
console_check_for_key(void)
|
||||||
{
|
{
|
||||||
char buffer[3];
|
char buffer[3];
|
||||||
ssize_t bytesRead = sInput.ReadAt(NULL, 0, buffer, 3);
|
ssize_t bytesRead = sConsole.ReadAt(NULL, 0, buffer, 3);
|
||||||
if (bytesRead <= 0)
|
if (bytesRead <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -406,7 +389,7 @@ console_check_for_key(void)
|
|||||||
|
|
||||||
// put back unread chars
|
// put back unread chars
|
||||||
if (bytesRead > 1)
|
if (bytesRead > 1)
|
||||||
sInput.PutChars(buffer + 1, bytesRead - 1);
|
sConsole.PutBackChars(buffer + 1, bytesRead - 1);
|
||||||
|
|
||||||
return buffer[0];
|
return buffer[0];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user