#include "qemu-common.h"
#include "console.h"
#include "qemu-timer.h"
+#include "qmp-commands.h"
//#define DEBUG_CONSOLE
#define DEFAULT_BACKSCROLL 512
active_console->hw_invalidate(active_console->hw);
}
-void vga_hw_screen_dump(const char *filename)
+void qmp_screendump(const char *filename, Error **errp)
{
TextConsole *previous_active_console;
bool cswitch;
console_select(0);
}
if (consoles[0] && consoles[0]->hw_screen_dump) {
- consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch);
+ consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
} else {
- error_report("screen dump not implemented");
+ error_setg(errp, "device doesn't support screendump\n");
}
if (cswitch) {
update_xy(s, x, y);
}
+/* set cursor, checking bounds */
+static void set_cursor(TextConsole *s, int x, int y)
+{
+ if (x < 0) {
+ x = 0;
+ }
+ if (y < 0) {
+ y = 0;
+ }
+ if (y >= s->height) {
+ y = s->height - 1;
+ }
+ if (x >= s->width) {
+ x = s->width - 1;
+ }
+
+ s->x = x;
+ s->y = y;
+}
+
static void console_putchar(TextConsole *s, int ch)
{
TextCell *c;
case TTY_STATE_CSI: /* handle escape sequence parameters */
if (ch >= '0' && ch <= '9') {
if (s->nb_esc_params < MAX_ESC_PARAMS) {
- s->esc_params[s->nb_esc_params] =
- s->esc_params[s->nb_esc_params] * 10 + ch - '0';
+ int *param = &s->esc_params[s->nb_esc_params];
+ int digit = (ch - '0');
+
+ *param = (*param <= (INT_MAX - digit) / 10) ?
+ *param * 10 + digit : INT_MAX;
}
} else {
- s->nb_esc_params++;
+ if (s->nb_esc_params < MAX_ESC_PARAMS)
+ s->nb_esc_params++;
if (ch == ';')
break;
#ifdef DEBUG_CONSOLE
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
- s->y -= s->esc_params[0];
- if (s->y < 0) {
- s->y = 0;
- }
+ set_cursor(s, s->x, s->y - s->esc_params[0]);
break;
case 'B':
/* move cursor down */
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
- s->y += s->esc_params[0];
- if (s->y >= s->height) {
- s->y = s->height - 1;
- }
+ set_cursor(s, s->x, s->y + s->esc_params[0]);
break;
case 'C':
/* move cursor right */
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
- s->x += s->esc_params[0];
- if (s->x >= s->width) {
- s->x = s->width - 1;
- }
+ set_cursor(s, s->x + s->esc_params[0], s->y);
break;
case 'D':
/* move cursor left */
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
- s->x -= s->esc_params[0];
- if (s->x < 0) {
- s->x = 0;
- }
+ set_cursor(s, s->x - s->esc_params[0], s->y);
break;
case 'G':
/* move cursor to column */
- s->x = s->esc_params[0] - 1;
- if (s->x < 0) {
- s->x = 0;
- }
+ set_cursor(s, s->esc_params[0] - 1, s->y);
break;
case 'f':
case 'H':
/* move cursor to row, column */
- s->x = s->esc_params[1] - 1;
- if (s->x < 0) {
- s->x = 0;
- }
- s->y = s->esc_params[0] - 1;
- if (s->y < 0) {
- s->y = 0;
- }
+ set_cursor(s, s->esc_params[1] - 1, s->esc_params[0] - 1);
break;
case 'J':
switch (s->esc_params[0]) {
if (s) {
DisplayState *ds = s->ds;
- if (active_console->cursor_timer) {
+ if (active_console && active_console->cursor_timer) {
qemu_del_timer(active_console->cursor_timer);
}
active_console = s;
memset(&pf, 0x00, sizeof(PixelFormat));
pf.bits_per_pixel = bpp;
- pf.bytes_per_pixel = bpp / 8;
+ pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
pf.depth = bpp == 32 ? 24 : bpp;
switch (bpp) {
memset(&pf, 0x00, sizeof(PixelFormat));
pf.bits_per_pixel = bpp;
- pf.bytes_per_pixel = bpp / 8;
+ pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
pf.depth = bpp == 32 ? 24 : bpp;
switch (bpp) {
case 15:
pf.bits_per_pixel = 16;
- pf.bytes_per_pixel = 2;
pf.rmask = 0x00007c00;
pf.gmask = 0x000003E0;
pf.bmask = 0x0000001F;