Added console support functions required for the generic textual boot
menu. The menu basically works, but has a couple of problems. The harmless ones are graphical: we get cursor artifacts when the colors are changed, and the item selection doesn't quite look as it should. More serious is the lack of Home/End, Page Up/Down keys. All I read from the console is a '\0' byte when such a key is pressed. The cursor keys work fortunately. I mapped the functionality of Page Up/Down additionally to the Left/Right cursor keys. So the menu should be usable at least. I guess, I'll leave it in that state; Axel wants a graphical menu anyway. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15589 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b821cecc36
commit
44c11fdbc1
@ -3,21 +3,24 @@ SubDir HAIKU_TOP src system boot platform openfirmware ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
KernelMergeObject boot_platform_openfirmware.o :
|
||||
<$(SOURCE_GRIST)>start.c
|
||||
<$(SOURCE_GRIST)>openfirmware.c
|
||||
<$(SOURCE_GRIST)>debug.c
|
||||
<$(SOURCE_GRIST)>mmu.cpp
|
||||
<$(SOURCE_GRIST)>Handle.cpp
|
||||
<$(SOURCE_GRIST)>devices.cpp
|
||||
<$(SOURCE_GRIST)>console.cpp
|
||||
<$(SOURCE_GRIST)>heap.cpp
|
||||
<$(SOURCE_GRIST)>video.cpp
|
||||
<$(SOURCE_GRIST)>menu.cpp
|
||||
console.cpp
|
||||
debug.c
|
||||
devices.cpp
|
||||
Handle.cpp
|
||||
heap.cpp
|
||||
menu.cpp
|
||||
mmu.cpp
|
||||
openfirmware.c
|
||||
start.c
|
||||
video.cpp
|
||||
|
||||
# generic
|
||||
text_menu.cpp
|
||||
:
|
||||
: boot_platform_openfirmware_$(TARGET_ARCH).a
|
||||
;
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles crt0.S ]
|
||||
= [ FDirName $(HAIKU_TOP) src system boot arch $(TARGET_ARCH) ] ;
|
||||
SEARCH on [ FGristFiles text_menu.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system boot platform generic ] ;
|
||||
|
||||
SubInclude HAIKU_TOP src system boot platform openfirmware arch ;
|
||||
|
@ -17,12 +17,36 @@ class ConsoleHandle : public Handle {
|
||||
public:
|
||||
ConsoleHandle();
|
||||
|
||||
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);
|
||||
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);
|
||||
};
|
||||
|
||||
static ConsoleHandle sInput, sOutput;
|
||||
class InputConsoleHandle : public ConsoleHandle {
|
||||
public:
|
||||
InputConsoleHandle();
|
||||
|
||||
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);
|
||||
char GetChar();
|
||||
|
||||
private:
|
||||
enum { BUFFER_SIZE = 32 };
|
||||
|
||||
char fBuffer[BUFFER_SIZE];
|
||||
int fStart;
|
||||
int fCount;
|
||||
};
|
||||
|
||||
|
||||
static InputConsoleHandle sInput;
|
||||
static ConsoleHandle sOutput;
|
||||
FILE *stdin, *stdout, *stderr;
|
||||
static bool sCursorVisible = true;
|
||||
|
||||
|
||||
ConsoleHandle::ConsoleHandle()
|
||||
@ -32,7 +56,8 @@ ConsoleHandle::ConsoleHandle()
|
||||
|
||||
|
||||
ssize_t
|
||||
ConsoleHandle::ReadAt(void */*cookie*/, off_t /*pos*/, void *buffer, size_t bufferSize)
|
||||
ConsoleHandle::ReadAt(void */*cookie*/, off_t /*pos*/, void *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
// don't seek in character devices
|
||||
return of_read(fHandle, buffer, bufferSize);
|
||||
@ -40,7 +65,8 @@ ConsoleHandle::ReadAt(void */*cookie*/, off_t /*pos*/, void *buffer, size_t buff
|
||||
|
||||
|
||||
ssize_t
|
||||
ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer, size_t bufferSize)
|
||||
ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
|
||||
size_t bufferSize)
|
||||
{
|
||||
const char *string = (const char *)buffer;
|
||||
|
||||
@ -81,6 +107,76 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer, size
|
||||
// #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)
|
||||
{
|
||||
if (fCount >= BUFFER_SIZE)
|
||||
return;
|
||||
|
||||
int pos = (fStart + fCount) % BUFFER_SIZE;
|
||||
fBuffer[pos] = c;
|
||||
fCount++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InputConsoleHandle::PutChars(const char *buffer, int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
PutChar(buffer[i]);
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
InputConsoleHandle::GetChar()
|
||||
{
|
||||
if (fCount == 0)
|
||||
return 0;
|
||||
|
||||
fCount--;
|
||||
char c = fBuffer[fStart];
|
||||
fStart = (fStart + 1) % BUFFER_SIZE;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
console_init(void)
|
||||
{
|
||||
@ -101,3 +197,130 @@ console_init(void)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
console_clear_screen(void)
|
||||
{
|
||||
of_interpret("erase-screen", 0, 0);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
console_width(void)
|
||||
{
|
||||
int columnCount;
|
||||
if (of_interpret("#columns", 0, 1, &columnCount) == OF_FAILED)
|
||||
return 0;
|
||||
return columnCount;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
console_height(void)
|
||||
{
|
||||
int lineCount;
|
||||
if (of_interpret("#lines", 0, 1, &lineCount) == OF_FAILED)
|
||||
return 0;
|
||||
return lineCount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
console_set_cursor(int32 x, int32 y)
|
||||
{
|
||||
// Note: We toggle the cursor temporarily to prevent a cursor artifact at
|
||||
// at the old location.
|
||||
of_interpret("toggle-cursor"
|
||||
" to line#"
|
||||
" to column#"
|
||||
" toggle-cursor",
|
||||
2, 0, y, x);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
translate_color(int32 color)
|
||||
{
|
||||
/*
|
||||
r g b
|
||||
0: 0 0 0 // black
|
||||
1: 0 0 aa // dark blue
|
||||
2: 0 aa 0 // dark green
|
||||
3: 0 aa aa // cyan
|
||||
4: aa 0 0 // dark red
|
||||
5: aa 0 aa // purple
|
||||
6: aa 55 0 // brown
|
||||
7: aa aa aa // light gray
|
||||
8: 55 55 55 // dark gray
|
||||
9: 55 55 ff // light blue
|
||||
a: 55 ff 55 // light green
|
||||
b: 55 ff ff // light cyan
|
||||
c: ff 55 55 // light red
|
||||
d: ff 55 ff // magenta
|
||||
e: ff ff 55 // yellow
|
||||
f: ff ff ff // white
|
||||
*/
|
||||
if (color >= 0 && color < 16)
|
||||
return color;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
console_set_color(int32 foreground, int32 background)
|
||||
{
|
||||
// Note: Toggling the cursor doesn't seem to help. We still get cursor
|
||||
// artifacts.
|
||||
of_interpret("toggle-cursor"
|
||||
" to foreground-color"
|
||||
" to background-color"
|
||||
" toggle-cursor",
|
||||
2, 0, translate_color(foreground), translate_color(background));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
console_wait_for_key(void)
|
||||
{
|
||||
// wait for a key
|
||||
char buffer[3];
|
||||
ssize_t bytesRead;
|
||||
do {
|
||||
bytesRead = sInput.ReadAt(NULL, 0, buffer, 3);
|
||||
if (bytesRead < 0)
|
||||
return 0;
|
||||
} while (bytesRead == 0);
|
||||
|
||||
// translate the ESC sequences for cursor keys
|
||||
if (bytesRead == 3 && buffer[0] == 27 && buffer [1] == 91) {
|
||||
switch (buffer[2]) {
|
||||
case 65:
|
||||
return TEXT_CONSOLE_KEY_UP;
|
||||
case 66:
|
||||
return TEXT_CONSOLE_KEY_DOWN;
|
||||
case 67:
|
||||
return TEXT_CONSOLE_KEY_RIGHT;
|
||||
case 68:
|
||||
return TEXT_CONSOLE_KEY_LEFT;
|
||||
// TODO: Translate the codes for the following keys. Unfortunately my OF just
|
||||
// returns a '\0' character. :-/
|
||||
// TEXT_CONSOLE_KEY_PAGE_UP,
|
||||
// TEXT_CONSOLE_KEY_PAGE_DOWN,
|
||||
// TEXT_CONSOLE_KEY_HOME,
|
||||
// TEXT_CONSOLE_KEY_END,
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// put back unread chars
|
||||
if (bytesRead > 1)
|
||||
sInput.PutChars(buffer + 1, bytesRead - 1);
|
||||
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,7 @@
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/stdio.h>
|
||||
|
||||
#include "Handle.h"
|
||||
|
||||
#include <boot/platform/generic/text_console.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -18,10 +13,6 @@ extern "C" {
|
||||
|
||||
extern status_t console_init(void);
|
||||
|
||||
extern status_t set_cursor_pos(FILE *, int x, int y);
|
||||
extern status_t set_foreground_color(FILE *, int c);
|
||||
extern status_t set_background_color(FILE *, int c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <boot/platform.h>
|
||||
#include <boot/menu.h>
|
||||
#include <boot/platform/generic/text_menu.h>
|
||||
|
||||
|
||||
void
|
||||
@ -27,16 +28,13 @@ platform_add_menus(Menu *menu)
|
||||
void
|
||||
platform_update_menu_item(Menu *menu, MenuItem *item)
|
||||
{
|
||||
if (menu->IsHidden())
|
||||
return;
|
||||
|
||||
// ToDo: implement me!
|
||||
platform_generic_update_text_menu_item(menu, item);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
platform_run_menu(Menu *menu)
|
||||
{
|
||||
// ToDo: implement me!
|
||||
platform_generic_run_text_menu(menu);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user