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>
This commit is contained in:
Gerd Hoffmann 2013-03-12 14:48:31 +01:00
parent 321f048d24
commit 2c62f08ddb
26 changed files with 74 additions and 452 deletions

View file

@ -56,11 +56,6 @@ typedef struct TCXState {
uint8_t dac_index, dac_state;
} TCXState;
static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
Error **errp);
static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
Error **errp);
static void tcx_set_dirty(TCXState *s)
{
memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
@ -569,7 +564,7 @@ static int tcx_init1(SysBusDevice *dev)
s->con = graphic_console_init(tcx24_update_display,
tcx24_invalidate_display,
tcx24_screen_dump, NULL, s);
NULL, s);
} else {
/* THC 8 bit (dummy) */
memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
@ -578,133 +573,13 @@ static int tcx_init1(SysBusDevice *dev)
s->con = graphic_console_init(tcx_update_display,
tcx_invalidate_display,
tcx_screen_dump, NULL, s);
NULL, s);
}
qemu_console_resize(s->con, s->width, s->height);
return 0;
}
static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
Error **errp)
{
TCXState *s = opaque;
FILE *f;
uint8_t *d, *d1, v;
int ret, y, x;
f = fopen(filename, "wb");
if (!f) {
error_setg(errp, "failed to open file '%s': %s", filename,
strerror(errno));
return;
}
ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
if (ret < 0) {
goto write_err;
}
d1 = s->vram;
for(y = 0; y < s->height; y++) {
d = d1;
for(x = 0; x < s->width; x++) {
v = *d;
ret = fputc(s->r[v], f);
if (ret == EOF) {
goto write_err;
}
ret = fputc(s->g[v], f);
if (ret == EOF) {
goto write_err;
}
ret = fputc(s->b[v], f);
if (ret == EOF) {
goto write_err;
}
d++;
}
d1 += MAXX;
}
out:
fclose(f);
return;
write_err:
error_setg(errp, "failed to write to file '%s': %s", filename,
strerror(errno));
unlink(filename);
goto out;
}
static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
Error **errp)
{
TCXState *s = opaque;
FILE *f;
uint8_t *d, *d1, v;
uint32_t *s24, *cptr, dval;
int ret, y, x;
f = fopen(filename, "wb");
if (!f) {
error_setg(errp, "failed to open file '%s': %s", filename,
strerror(errno));
return;
}
ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
if (ret < 0) {
goto write_err;
}
d1 = s->vram;
s24 = s->vram24;
cptr = s->cplane;
for(y = 0; y < s->height; y++) {
d = d1;
for(x = 0; x < s->width; x++, d++, s24++) {
if ((*cptr++ & 0xff000000) == 0x03000000) { // 24-bit direct
dval = *s24 & 0x00ffffff;
ret = fputc((dval >> 16) & 0xff, f);
if (ret == EOF) {
goto write_err;
}
ret = fputc((dval >> 8) & 0xff, f);
if (ret == EOF) {
goto write_err;
}
ret = fputc(dval & 0xff, f);
if (ret == EOF) {
goto write_err;
}
} else {
v = *d;
ret = fputc(s->r[v], f);
if (ret == EOF) {
goto write_err;
}
ret = fputc(s->g[v], f);
if (ret == EOF) {
goto write_err;
}
ret = fputc(s->b[v], f);
if (ret == EOF) {
goto write_err;
}
}
}
d1 += MAXX;
}
out:
fclose(f);
return;
write_err:
error_setg(errp, "failed to write to file '%s': %s", filename,
strerror(errno));
unlink(filename);
goto out;
}
static Property tcx_properties[] = {
DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
DEFINE_PROP_UINT16("width", TCXState, width, -1),