Rework the ConsoleDevice to be a full featured window based console.

Only looses high intensity color from the plain console, but doesn't eat keystrokes, and a 2nd window opens for dprintf stuff.
Only Amiga makes it possible ;-)
http://revolf.free.fr/beos/shots/shot_haiku_loader_amiga_m68k_004.png


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39264 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol
2010-11-01 22:35:43 +00:00
parent a528bdee7f
commit 4219bd961b
4 changed files with 321 additions and 40 deletions
+232 -38
View File
@@ -24,7 +24,11 @@ class ConsoleHandle : public CharHandle {
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer,
size_t bufferSize);
void Clear();
void MoveTo(int16 x, int16 y);
void SetColor(int32 foreground, int32 background);
int Columns();
int Rows();
private:
static int16 fX;
@@ -34,7 +38,7 @@ class ConsoleHandle : public CharHandle {
class ConsoleDevice : public ExecDevice {
public:
ConsoleDevice();
ConsoleDevice(const char *title);
virtual ~ConsoleDevice();
status_t Open();
@@ -42,9 +46,19 @@ class ConsoleDevice : public ExecDevice {
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);
void Clear();
void MoveTo(int16 x, int16 y);
void SetColor(int32 foreground, int32 background);
int Columns();
int Rows();
int WaitForKey();
protected:
const char *fTitle;
struct Window *fWindow;
int fRows, fCols;
};
class KeyboardDevice : public ExecDevice {
@@ -155,6 +169,14 @@ ConsoleHandle::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
}
void
ConsoleHandle::Clear()
{
Move(&gScreen->RastPort, 0, sScreenTopOffset);
ClearScreen(&gScreen->RastPort);
}
void
ConsoleHandle::MoveTo(int16 x, int16 y)
{
@@ -167,11 +189,37 @@ ConsoleHandle::MoveTo(int16 x, int16 y)
}
void
ConsoleHandle::SetColor(int32 foreground, int32 background)
{
SetAPen(&gScreen->RastPort, foreground);
SetBPen(&gScreen->RastPort, background);
}
int
ConsoleHandle::Columns()
{
int columnCount = gScreen->Width / sFontWidth;
return columnCount;
}
int
ConsoleHandle::Rows()
{
int lineCount = (gScreen->Height - sScreenTopOffset) / sFontHeight;
return lineCount;
}
// #pragma mark -
ConsoleDevice::ConsoleDevice()
: ExecDevice()
ConsoleDevice::ConsoleDevice(const char *title)
: ExecDevice(),
fTitle(title),
fWindow(NULL)
{
}
@@ -184,7 +232,57 @@ ConsoleDevice::~ConsoleDevice()
status_t
ConsoleDevice::Open()
{
return ExecDevice::Open("console.device", -1);
status_t err;
if (fWindow)
return B_ERROR;
err = AllocRequest(sizeof(struct IOStdReq));
if (err < B_OK)
panic("AllocRequest");;
if (err < B_OK)
return err;
int16 topEdge = gScreen->Height - 60;
int height = 60;
if (fTitle == NULL) {
topEdge = 10;
height = gScreen->Height - 40;
fTitle = "Console";
}
struct NewWindow newWindow = {
0, topEdge,
gScreen->Width, height,
BLACK, WHITE,
IDCMP_CLOSEWINDOW,
WFLG_SIZEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIMPLE_REFRESH
| WFLG_ACTIVATE,
NULL,
NULL,
fTitle,
gScreen,
NULL,
100, 45,
gScreen->Width, gScreen->Height,
CUSTOMSCREEN
};
fWindow = OpenWindow(&newWindow);
if (fWindow == NULL)
panic("OpenWindow");;
if (fWindow == NULL)
return B_ERROR;
fIOStdReq->io_Data = fWindow;
fIOStdReq->io_Length = sizeof(struct Window);
err = ExecDevice::Open(CONSOLENAME, CONU_STANDARD, 0);
if (err < B_OK)
return err;
MoveTo(0, 0);
SetColor(WHITE, BLACK);
Clear();
}
@@ -200,27 +298,44 @@ ConsoleDevice::WaitForKey()
{
char ascii;
if (Read(&ascii, 1) < 1) {
panic("WFK\n");
return 0;
}
dprintf("ascii %d %c\n", ascii, ascii);
if (Read(&ascii, 1) < 1)
return TEXT_CONSOLE_NO_KEY;
//dprintf("ascii %d %c\n", ascii, ascii);
switch (ascii) {
case IECODE_KEY_UP:
return TEXT_CONSOLE_KEY_UP;
case IECODE_KEY_DOWN:
return TEXT_CONSOLE_KEY_DOWN;
case IECODE_KEY_LEFT:
return TEXT_CONSOLE_KEY_LEFT;
case IECODE_KEY_RIGHT:
return TEXT_CONSOLE_KEY_RIGHT;
case IECODE_KEY_PAGE_UP:
return TEXT_CONSOLE_KEY_PAGE_UP;
case IECODE_KEY_PAGE_DOWN:
return TEXT_CONSOLE_KEY_PAGE_DOWN;
default:
break;
if (ascii == (char)0x9b) {
if (Read(&ascii, 1) < 1)
return TEXT_CONSOLE_NO_KEY;
//dprintf(">ascii %d %c\n", ascii, ascii);
switch (ascii) {
case 'A':
return TEXT_CONSOLE_KEY_UP;
case 'B':
return TEXT_CONSOLE_KEY_DOWN;
case 'D':
return TEXT_CONSOLE_KEY_LEFT;
case 'C':
return TEXT_CONSOLE_KEY_RIGHT;
case '4':
{
if (Read(&ascii, 1) < 1)
return TEXT_CONSOLE_NO_KEY;
if (ascii == '~')
return TEXT_CONSOLE_NO_KEY;
switch (ascii) {
case '1':
Read(&ascii, 1); // ~
return TEXT_CONSOLE_KEY_PAGE_UP;
case '2':
Read(&ascii, 1); // ~
return TEXT_CONSOLE_KEY_PAGE_UP;
default:
return TEXT_CONSOLE_NO_KEY;
}
return TEXT_CONSOLE_NO_KEY;
}
default:
break;
}
}
return ascii;
}
@@ -233,6 +348,74 @@ ConsoleDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t buffe
}
void
ConsoleDevice::Clear()
{
char buff[] = "\x0c";
WriteAt(NULL, 0LL, buff, sizeof(buff) - 1);
}
void
ConsoleDevice::MoveTo(int16 x, int16 y)
{
char buff[32];
x = MIN(79,MAX(0,x));
y = MIN(24,MAX(0,y));
sprintf(buff, "\x9b%02d;%02d\x48", y + 1, x + 1);
//buff[4] += (char)x;
//buff[2] += (char)y;
WriteAt(NULL, 0LL, buff, strlen(buff));
}
void
ConsoleDevice::SetColor(int32 foreground, int32 background)
{
//char buff[] = "\x9b37;40m";
char buff[] = "\2330;30;40m";
if (foreground >= 8) {
foreground -= 8;
//buff[1] = '1'; // bold
}
// else
// buff[1] = '2';
//if (background >= 8)
// background -= 8;
if (foreground == background) {
foreground = 7 - background;
}
if (foreground < 8)
buff[4] += foreground;
if (background < 8)
buff[7] += background;
WriteAt(NULL, 0LL, buff, sizeof(buff) - 1);
}
int
ConsoleDevice::Columns()
{
struct ConUnit *unit = (struct ConUnit *)fIOStdReq->io_Unit;
return unit->cu_XMax;
}
int
ConsoleDevice::Rows()
{
struct ConUnit *unit = (struct ConUnit *)fIOStdReq->io_Unit;
return unit->cu_YMax - 1;
}
// #pragma mark -
@@ -445,11 +628,14 @@ LLKeyboardDevice::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bu
// #pragma mark -
static ConsoleHandle sOutput;
static ConsoleHandle sErrorOutput;
static ConsoleHandle sDebugOutput;
static ConsoleDevice sOutput(NULL);
//static ConsoleHandle sOutput;
//static ConsoleHandle sErrorOutput;
//static ConsoleHandle sDebugOutput;
static ConsoleDevice sDebugOutput("Debug");
static KeyboardDevice sInput;
//static KeyboardDevice sInput;
static ConsoleDevice &sInput = sOutput;
status_t
@@ -498,7 +684,18 @@ console_init(void)
//ClearScreen(&gScreen->RastPort);
dbgerr = stdout = stderr = (FILE *)&sOutput;
err = sDebugOutput.Open();
if (err < B_OK)
panic("sDebugOutput.Open() 0x%08lx\n", err);
dbgerr = stderr = (FILE *)&sDebugOutput;
err = sOutput.Open();
if (err < B_OK)
panic("sOutput.Open() 0x%08lx\n", err);
stdout = (FILE *)&sOutput;
console_set_cursor(0, 0);
@@ -526,10 +723,11 @@ console_init(void)
panic("Cannot open %s", KEYMAPNAME);
sInput.AllocRequest(sizeof(struct IOStdReq));
/*
err = sInput.Open();
if (err < B_OK)
panic("sInput.Open() 0x%08lx\n", err);
*/
stdin = (FILE *)&sInput;
return B_OK;
@@ -542,24 +740,21 @@ console_init(void)
void
console_clear_screen(void)
{
Move(&gScreen->RastPort, 0, sScreenTopOffset);
ClearScreen(&gScreen->RastPort);
sOutput.Clear();
}
int32
console_width(void)
{
int columnCount = gScreen->Width / sFontWidth;
return columnCount;
return sOutput.Columns();
}
int32
console_height(void)
{
int lineCount = (gScreen->Height - sScreenTopOffset) / sFontHeight;
return lineCount;
return sOutput.Rows();
}
@@ -573,8 +768,7 @@ console_set_cursor(int32 x, int32 y)
void
console_set_color(int32 foreground, int32 background)
{
SetAPen(&gScreen->RastPort, foreground);
SetBPen(&gScreen->RastPort, background);
sOutput.SetColor(foreground, background);
}
@@ -51,6 +51,8 @@ ExecDevice::ExecDevice(size_t requestSize)
ExecDevice::ExecDevice()
{
fIORequest = NULL;
fIOStdReq = NULL;
}
@@ -72,7 +74,7 @@ ExecDevice::AllocRequest(size_t requestSize)
if (fIORequest == NULL)
panic("CreateIORequest()");
fIOStdReq = (struct IOStdReq *)fIORequest;
return B_ERROR;
return B_OK;
}
@@ -969,6 +969,14 @@ struct ListNode {
const char *ln_Name;
};
struct List {
struct ListNode *lh_Head;
struct ListNode *lh_Tail;
struct ListNode *lh_TailPred;
uint8 lh_Type;
uint8 lh_pad;
};
// <exec/lists.h>
@@ -1016,6 +1024,14 @@ struct Message {
uint16 mn_Length;
} _PACKED;
struct MsgPort {
struct ListNode mp_Node;
uint8 mp_Flags;
uint8 mp_SigBits;
void *mp_SigTask;
struct List mp_MsgList;
} _PACKED;
#endif /* __ASSEMBLER__ */
@@ -1402,6 +1418,44 @@ struct NameInfo {
#ifndef __ASSEMBLER__
struct Window {
uint8 dummy1[136];
};
struct NewWindow {
int16 LeftEdge, TopEdge;
int16 Width, Height;
uint8 DetailPen, BlockPen;
uint32 IDCMPFlags;
uint32 Flags;
struct Gadget *FirstGadget;
struct Image *CheckMark;
const char *Title;
struct Screen *Screen;
struct BitMap *BitMap;
int16 MinWidth, MinHeight;
uint16 MaxWidth, MaxHeight;
uint16 Type;
};
#endif /* __ASSEMBLER__ */
#define CUSTOMSCREEN 0x000f
#define IDCMP_CLOSEWINDOW 0x00000200
#define WFLG_SIZEGADGET 0x00000001
#define WFLG_DRAGBAR 0x00000002
#define WFLG_DEPTHGADGET 0x00000004
#define WFLG_CLOSEGADGET 0x00000008
#define WFLG_SMART_REFRESH 0x00000000
#define WFLG_SIMPLE_REFRESH 0x00000040
#define WFLG_ACTIVATE 0x00001000
#ifndef __ASSEMBLER__
// <intuition/screen.h>
struct NewScreen {
@@ -1448,10 +1502,39 @@ extern struct Library *INTUITION_BASE_NAME;
LP1(0xc6, struct Screen *, OpenScreen, struct NewScreen *, last, a0, \
, INTUITION_BASE_NAME)
#define OpenWindow(last) \
LP1(0xcc, struct Window *, OpenWindow, struct NewWindow *, last, a0, \
, INTUITION_BASE_NAME)
#define RemakeDisplay() \
LP0(0x180, int32, RemakeDisplay, \
, INTUITION_BASE_NAME)
#endif /* __ASSEMBLER__ */
// <devices/conunit.h>
#define CONU_LIBRARY -1
#define CONU_STANDARD 0
#define CONU_CHARMAP 1
#ifndef __ASSEMBLER__
struct ConUnit {
struct MsgPort cu_MP;
struct Window *cu_Window;
int16 cu_XCP, cu_YCP;
int16 cu_XMax, cu_YMax;
};
#endif /* __ASSEMBLER__ */
// <devices/console.h>
#define CONSOLENAME "console.device"
// <devices/keymap.h>
#ifndef KEYMAP_BASE_NAME
@@ -234,7 +234,7 @@ platform_switch_to_logo(void)
sFrameBuffer = gKernelArgs.frame_buffer.physical_buffer.start;
video_display_splash(sFrameBuffer);
//video_display_splash(sFrameBuffer);
}
@@ -243,6 +243,8 @@ extern "C" void
platform_switch_to_text_mode(void)
{
// TODO: implement me
// force Intuition to redraw everything
RemakeDisplay();
}