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