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:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user