* Based on ahwayakchih's blue screen paging code (see bug #1444), I added

paging support to KDL (but not the on-screen debug output for now).
* Defaults to "on", use the new "paging" KDL command to turn it off (or on
  again).
* When pressing 'q' while it is waiting for a key, it will now eat the rest
  of the commands output (helpful for slow screen output of a large data set).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23566 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-01-16 20:39:00 +00:00
parent b9074efcb7
commit 855ab2b312
3 changed files with 126 additions and 23 deletions
+108 -22
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2007, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2005-2008, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -14,6 +14,8 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include "debug_commands.h"
#define USE_SCROLLING 0 #define USE_SCROLLING 0
#define NO_CLEAR 1 #define NO_CLEAR 1
@@ -44,6 +46,9 @@ struct screen_info {
uint8 attr; uint8 attr;
bool bright_attr; bool bright_attr;
bool reverse_attr; bool reverse_attr;
int32 in_command_rows;
bool paging;
bool ignore_output;
// state machine // state machine
console_state state; console_state state;
@@ -79,8 +84,9 @@ move_cursor(int32 x, int32 y)
#if USE_SCROLLING #if USE_SCROLLING
/** scroll from the cursor line up to the top of the scroll region up one line */ /*! Scroll from the cursor line up to the top of the scroll region up one
line.
*/
static void static void
scroll_up(void) scroll_up(void)
{ {
@@ -96,18 +102,51 @@ scroll_up(void)
static void static void
next_line(void) next_line(void)
{ {
if (in_command_invocation())
sScreen.in_command_rows++;
else
sScreen.in_command_rows = 0;
if (sScreen.y == sScreen.rows - 1) { if (sScreen.y == sScreen.rows - 1) {
#if USE_SCROLLING #if USE_SCROLLING
scroll_up(); scroll_up();
#else #else
if (sScreen.paging && sScreen.in_command_rows > 1) {
// We're in the debugger, and a command is being executed
const char *text = "Press key to continue, Q to quit";
int32 length = strlen(text);
if (sScreen.x + length > sScreen.columns) {
// make sure we don't overwrite too much
text = "P";
length = 1;
}
for (int32 i = 0; i < length; i++) {
sModule->put_glyph(sScreen.columns - length + i, sScreen.y,
text[i], 0xf0);
}
char c = blue_screen_getchar();
if (c == 'q')
sScreen.ignore_output = true;
// remove on screen text again
sModule->fill_glyph(sScreen.columns - length, sScreen.y, length,
1, ' ', sScreen.attr);
}
sScreen.y = 0; sScreen.y = 0;
sModule->fill_glyph(0, 0, sScreen.columns, 2, ' ', sScreen.attr);
#endif #endif
} else if (sScreen.y < sScreen.rows - 1) { } else if (sScreen.y < sScreen.rows - 1) {
sScreen.y++; sScreen.y++;
} }
#if NO_CLEAR #if NO_CLEAR
sModule->fill_glyph(0, (sScreen.y + 2) % sScreen.rows, sScreen.columns, 1, ' ', sScreen.attr); if (sScreen.y + 2 < sScreen.rows) {
sModule->fill_glyph(0, (sScreen.y + 2) % sScreen.rows, sScreen.columns,
1, ' ', sScreen.attr);
}
#endif #endif
sScreen.x = 0; sScreen.x = 0;
} }
@@ -118,14 +157,16 @@ erase_line(erase_line_mode mode)
{ {
switch (mode) { switch (mode) {
case LINE_ERASE_WHOLE: case LINE_ERASE_WHOLE:
sModule->fill_glyph(0, sScreen.y, sScreen.columns, 1, ' ', sScreen.attr); sModule->fill_glyph(0, sScreen.y, sScreen.columns, 1, ' ',
sScreen.attr);
break; break;
case LINE_ERASE_LEFT: case LINE_ERASE_LEFT:
sModule->fill_glyph(0, sScreen.y, sScreen.x + 1, 1, ' ', sScreen.attr); sModule->fill_glyph(0, sScreen.y, sScreen.x + 1, 1, ' ',
sScreen.attr);
break; break;
case LINE_ERASE_RIGHT: case LINE_ERASE_RIGHT:
sModule->fill_glyph(sScreen.x, sScreen.y, sScreen.columns - sScreen.x, sModule->fill_glyph(sScreen.x, sScreen.y, sScreen.columns
1, ' ', sScreen.attr); - sScreen.x, 1, ' ', sScreen.attr);
break; break;
// default: // default:
} }
@@ -186,7 +227,8 @@ set_vt100_attributes(int32 *args, int32 argCount)
break; break;
case 7: // reverse case 7: // reverse
sScreen.reverse_attr = true; sScreen.reverse_attr = true;
sScreen.attr = ((sScreen.attr & BMASK) >> 4) | ((sScreen.attr & FMASK) << 4); sScreen.attr = ((sScreen.attr & BMASK) >> 4)
| ((sScreen.attr & FMASK) << 4);
if (sScreen.bright_attr) if (sScreen.bright_attr)
sScreen.attr |= 0x08; sScreen.attr |= 0x08;
break; break;
@@ -194,14 +236,20 @@ set_vt100_attributes(int32 *args, int32 argCount)
break; break;
/* foreground colors */ /* foreground colors */
case 30: sScreen.attr = (sScreen.attr & ~FMASK) | 0 | (sScreen.bright_attr ? 0x08 : 0); break; // black case 30: // black
case 31: sScreen.attr = (sScreen.attr & ~FMASK) | 4 | (sScreen.bright_attr ? 0x08 : 0); break; // red case 31: // red
case 32: sScreen.attr = (sScreen.attr & ~FMASK) | 2 | (sScreen.bright_attr ? 0x08 : 0); break; // green case 32: // green
case 33: sScreen.attr = (sScreen.attr & ~FMASK) | 6 | (sScreen.bright_attr ? 0x08 : 0); break; // yellow case 33: // yellow
case 34: sScreen.attr = (sScreen.attr & ~FMASK) | 1 | (sScreen.bright_attr ? 0x08 : 0); break; // blue case 34: // blue
case 35: sScreen.attr = (sScreen.attr & ~FMASK) | 5 | (sScreen.bright_attr ? 0x08 : 0); break; // magenta case 35: // magenta
case 36: sScreen.attr = (sScreen.attr & ~FMASK) | 3 | (sScreen.bright_attr ? 0x08 : 0); break; // cyan case 36: // cyan
case 37: sScreen.attr = (sScreen.attr & ~FMASK) | 7 | (sScreen.bright_attr ? 0x08 : 0); break; // white case 37: // white
{
const uint8 colors[] = {0, 4, 2, 6, 1, 5, 3, 7};
sScreen.attr = (sScreen.attr & ~FMASK) | colors[args[i] - 30]
| (sScreen.bright_attr ? 0x08 : 0);
break;
}
/* background colors */ /* background colors */
case 40: sScreen.attr = (sScreen.attr & ~BMASK) | (0 << 4); break; // black case 40: sScreen.attr = (sScreen.attr & ~BMASK) | (0 << 4); break; // black
@@ -415,7 +463,8 @@ parse_character(char c)
break; break;
default: default:
sScreen.args[sScreen.arg_count] = 0; sScreen.args[sScreen.arg_count] = 0;
process_vt100_command(c, false, sScreen.args, sScreen.arg_count + 1); process_vt100_command(c, false, sScreen.args,
sScreen.arg_count + 1);
sScreen.state = CONSOLE_STATE_NORMAL; sScreen.state = CONSOLE_STATE_NORMAL;
} }
break; break;
@@ -427,10 +476,12 @@ parse_character(char c)
sScreen.state = CONSOLE_STATE_PARSING_ARG; sScreen.state = CONSOLE_STATE_PARSING_ARG;
break; break;
case '?': case '?':
// private DEC mode parameter follows - we ignore those anyway // private DEC mode parameter follows - we ignore those
// anyway
break; break;
default: default:
process_vt100_command(c, true, sScreen.args, sScreen.arg_count + 1); process_vt100_command(c, true, sScreen.args,
sScreen.arg_count + 1);
sScreen.state = CONSOLE_STATE_NORMAL; sScreen.state = CONSOLE_STATE_NORMAL;
} }
break; break;
@@ -446,7 +497,8 @@ parse_character(char c)
sScreen.state = CONSOLE_STATE_PARSING_ARG; sScreen.state = CONSOLE_STATE_PARSING_ARG;
break; break;
default: default:
process_vt100_command(c, true, sScreen.args, sScreen.arg_count + 1); process_vt100_command(c, true, sScreen.args,
sScreen.arg_count + 1);
sScreen.state = CONSOLE_STATE_NORMAL; sScreen.state = CONSOLE_STATE_NORMAL;
} }
break; break;
@@ -461,13 +513,36 @@ parse_character(char c)
sScreen.state = CONSOLE_STATE_NEW_ARG; sScreen.state = CONSOLE_STATE_NEW_ARG;
break; break;
default: default:
process_vt100_command(c, true, sScreen.args, sScreen.arg_count + 1); process_vt100_command(c, true, sScreen.args,
sScreen.arg_count + 1);
sScreen.state = CONSOLE_STATE_NORMAL; sScreen.state = CONSOLE_STATE_NORMAL;
} }
} }
} }
static int
set_paging(int argc, char **argv)
{
if (argc > 1 && !strcmp(argv[1], "--help")) {
kprintf("usage: %s [on|off]\n", argv[0]);
return 0;
}
if (argc == 1)
sScreen.paging = !sScreen.paging;
else if (!strcmp(argv[1], "on"))
sScreen.paging = true;
else if (!strcmp(argv[1], "off"))
sScreen.paging = false;
else
sScreen.paging = parse_expression(argv[1]) != 0;
kprintf("paging is turned %s now.\n", sScreen.paging ? "on" : "off");
return 0;
}
// #pragma mark - // #pragma mark -
@@ -482,6 +557,9 @@ blue_screen_init(void)
return B_ERROR; return B_ERROR;
sModule = &gFrameBufferConsoleModule; sModule = &gFrameBufferConsoleModule;
sScreen.paging = true;
add_debugger_command("paging", set_paging, "Enable or disable paging");
return B_OK; return B_OK;
} }
@@ -517,6 +595,10 @@ blue_screen_getchar(void)
void void
blue_screen_putchar(char c) blue_screen_putchar(char c)
{ {
if (sScreen.ignore_output && in_command_invocation())
return;
sScreen.ignore_output = false;
hide_cursor(); hide_cursor();
parse_character(c); parse_character(c);
@@ -528,6 +610,10 @@ blue_screen_putchar(char c)
void void
blue_screen_puts(const char *text) blue_screen_puts(const char *text)
{ {
if (sScreen.ignore_output && in_command_invocation())
return;
sScreen.ignore_output = false;
hide_cursor(); hide_cursor();
while (text[0] != '\0') { while (text[0] != '\0') {
+16 -1
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2008, Ingo Weinhold, [email protected] * Copyright 2008, Ingo Weinhold, [email protected]
* Copyright 2002-2007, Axel Dörfler, [email protected] * Copyright 2002-2008, Axel Dörfler, [email protected]
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Copyright 2001, Travis Geiselbrecht. All rights reserved. * Copyright 2001, Travis Geiselbrecht. All rights reserved.
@@ -27,6 +27,7 @@ static struct debugger_command *sCommands;
static jmp_buf sInvokeCommandEnv; static jmp_buf sInvokeCommandEnv;
static bool sInvokeCommandDirectly = false; static bool sInvokeCommandDirectly = false;
static bool sInCommand = false;
debugger_command* debugger_command*
@@ -75,6 +76,15 @@ find_debugger_command(const char *name, bool partialMatch, bool& ambiguous)
} }
/*! Returns wether or not a debugger command is currently being invoked.
*/
bool
in_command_invocation(void)
{
return sInCommand;
}
/*! This function is a safe gate through which debugger commands are invoked. /*! This function is a safe gate through which debugger commands are invoked.
It sets a fault handler before invoking the command, so that an invalid It sets a fault handler before invoking the command, so that an invalid
memory access will not result in another KDL session on top of this one memory access will not result in another KDL session on top of this one
@@ -99,6 +109,8 @@ invoke_debugger_command(struct debugger_command *command, int argc, char** argv)
if (sInvokeCommandDirectly) if (sInvokeCommandDirectly)
return command->func(argc, argv); return command->func(argc, argv);
sInCommand = true;
if (setjmp(sInvokeCommandEnv) == 0) { if (setjmp(sInvokeCommandEnv) == 0) {
int result; int result;
thread->fault_handler = (addr_t)&&error; thread->fault_handler = (addr_t)&&error;
@@ -108,7 +120,9 @@ invoke_debugger_command(struct debugger_command *command, int argc, char** argv)
goto error; goto error;
result = command->func(argc, argv); result = command->func(argc, argv);
thread->fault_handler = oldFaultHandler; thread->fault_handler = oldFaultHandler;
sInCommand = false;
return result; return result;
error: error:
@@ -119,6 +133,7 @@ error:
} }
thread->fault_handler = oldFaultHandler; thread->fault_handler = oldFaultHandler;
sInCommand = false;
return 0; return 0;
} }
+2
View File
@@ -24,6 +24,8 @@ debugger_command* next_debugger_command(debugger_command* command,
const char* prefix, int prefixLen); const char* prefix, int prefixLen);
debugger_command* find_debugger_command(const char* name, bool partialMatch, debugger_command* find_debugger_command(const char* name, bool partialMatch,
bool& ambiguous); bool& ambiguous);
bool in_command_invocation(void);
int invoke_debugger_command(struct debugger_command *command, int argc, int invoke_debugger_command(struct debugger_command *command, int argc,
char** argv); char** argv);