mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 08:43:55 -06:00
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:
parent
321f048d24
commit
2c62f08ddb
26 changed files with 74 additions and 452 deletions
129
hw/display/tcx.c
129
hw/display/tcx.c
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue