aboutsummaryrefslogtreecommitdiff
path: root/ui/console.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2013-03-12 14:48:31 +0100
committerGerd Hoffmann <kraxel@redhat.com>2013-04-16 09:03:48 +0200
commit2c62f08ddbf3fa80dc7202eb9a2ea60ae44e2cc5 (patch)
tree7be759b610535361478fae83071cb9389c0a1d6c /ui/console.c
parent321f048d248472f1e90559976bb917d869981c68 (diff)
console: simplify screendump
Screendumps are alot simpler as we can update non-active QemuConsoles now. So we only need to update the QemuConsole we want write out, then dump the DisplaySurface content into a ppm file. Done. No console switching needed. No special support code in the gfx card emulation needed. Zap it all. Also move ppm_save out of the vga code and next to the qmp_screendump function. For now screen dumping is limited to console #0 (like it used to be), even though it is dead simple to extend it to other consoles. I wanna finish the console cleanup before setting new qapi interfaces into stone. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Tested-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
Diffstat (limited to 'ui/console.c')
-rw-r--r--ui/console.c72
1 files changed, 53 insertions, 19 deletions
diff --git a/ui/console.c b/ui/console.c
index e8e548e4c0..537b2fc52f 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -121,7 +121,6 @@ struct QemuConsole {
/* Graphic console state. */
graphic_hw_update_ptr hw_update;
graphic_hw_invalidate_ptr hw_invalidate;
- graphic_hw_screen_dump_ptr hw_screen_dump;
graphic_hw_text_update_ptr hw_text_update;
void *hw;
int g_width, g_height;
@@ -188,28 +187,65 @@ void graphic_hw_invalidate(QemuConsole *con)
}
}
-void qmp_screendump(const char *filename, Error **errp)
+static void ppm_save(const char *filename, struct DisplaySurface *ds,
+ Error **errp)
{
- QemuConsole *previous_active_console;
- bool cswitch;
-
- previous_active_console = active_console;
- cswitch = previous_active_console && previous_active_console->index != 0;
+ int width = pixman_image_get_width(ds->image);
+ int height = pixman_image_get_height(ds->image);
+ FILE *f;
+ int y;
+ int ret;
+ pixman_image_t *linebuf;
- /* There is currently no way of specifying which screen we want to dump,
- so always dump the first one. */
- if (cswitch) {
- console_select(0);
+ trace_ppm_save(filename, ds);
+ f = fopen(filename, "wb");
+ if (!f) {
+ error_setg(errp, "failed to open file '%s': %s", filename,
+ strerror(errno));
+ return;
}
- if (consoles[0] && consoles[0]->hw_screen_dump) {
- consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
- } else {
- error_setg(errp, "device doesn't support screendump");
+ ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
+ if (ret < 0) {
+ linebuf = NULL;
+ goto write_err;
+ }
+ linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
+ for (y = 0; y < height; y++) {
+ qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
+ clearerr(f);
+ ret = fwrite(pixman_image_get_data(linebuf), 1,
+ pixman_image_get_stride(linebuf), f);
+ (void)ret;
+ if (ferror(f)) {
+ goto write_err;
+ }
}
- if (cswitch) {
- console_select(previous_active_console->index);
+out:
+ qemu_pixman_image_unref(linebuf);
+ fclose(f);
+ return;
+
+write_err:
+ error_setg(errp, "failed to write to file '%s': %s", filename,
+ strerror(errno));
+ unlink(filename);
+ goto out;
+}
+
+void qmp_screendump(const char *filename, Error **errp)
+{
+ QemuConsole *con = consoles[0];
+ DisplaySurface *surface;
+
+ if (con == NULL) {
+ error_setg(errp, "There is no QemuConsole I can screendump from.");
+ return;
}
+
+ graphic_hw_update(con);
+ surface = qemu_console_surface(con);
+ ppm_save(filename, surface, errp);
}
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
@@ -1411,7 +1447,6 @@ DisplayState *init_displaystate(void)
QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
graphic_hw_invalidate_ptr invalidate,
- graphic_hw_screen_dump_ptr screen_dump,
graphic_hw_text_update_ptr text_update,
void *opaque)
{
@@ -1425,7 +1460,6 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
s = new_console(ds, GRAPHIC_CONSOLE);
s->hw_update = update;
s->hw_invalidate = invalidate;
- s->hw_screen_dump = screen_dump;
s->hw_text_update = text_update;
s->hw = opaque;