fix screendump (Stefano Stabellini)
this patch fixes the screendump functionality that was recently broken;
it must be applied *after* PATCH 5, 6 and 7 of the original displaystate
change patch series.
In fact the other patches make much easier to solve the screendump
problem because they make the console switching mechanism more robust.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6345 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/hw/vga.c b/hw/vga.c
index f376ca6..50bd85f 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2533,8 +2533,6 @@
/********************************************************/
/* vga screen dump */
-static int vga_save_w, vga_save_h;
-
static void vga_save_dpy_update(DisplayState *s,
int x, int y, int w, int h)
{
@@ -2548,30 +2546,39 @@
{
}
-int ppm_save(const char *filename, uint8_t *data,
- int w, int h, int linesize)
+int ppm_save(const char *filename, struct DisplaySurface *ds)
{
FILE *f;
uint8_t *d, *d1;
- unsigned int v;
+ uint32_t v;
int y, x;
+ uint8_t r, g, b;
f = fopen(filename, "wb");
if (!f)
return -1;
fprintf(f, "P6\n%d %d\n%d\n",
- w, h, 255);
- d1 = data;
- for(y = 0; y < h; y++) {
+ ds->width, ds->height, 255);
+ d1 = ds->data;
+ for(y = 0; y < ds->height; y++) {
d = d1;
- for(x = 0; x < w; x++) {
- v = *(uint32_t *)d;
- fputc((v >> 16) & 0xff, f);
- fputc((v >> 8) & 0xff, f);
- fputc((v) & 0xff, f);
- d += 4;
+ for(x = 0; x < ds->width; x++) {
+ if (ds->pf.bits_per_pixel == 32)
+ v = *(uint32_t *)d;
+ else
+ v = (uint32_t) (*(uint16_t *)d);
+ r = ((v >> ds->pf.rshift) & ds->pf.rmax) * 256 /
+ (ds->pf.rmax + 1);
+ g = ((v >> ds->pf.gshift) & ds->pf.gmax) * 256 /
+ (ds->pf.gmax + 1);
+ b = ((v >> ds->pf.bshift) & ds->pf.bmax) * 256 /
+ (ds->pf.bmax + 1);
+ fputc(r, f);
+ fputc(g, f);
+ fputc(b, f);
+ d += ds->pf.bytes_per_pixel;
}
- d1 += linesize;
+ d1 += ds->linesize;
}
fclose(f);
return 0;
@@ -2613,15 +2620,13 @@
dcl.dpy_resize = vga_save_dpy_resize;
dcl.dpy_refresh = vga_save_dpy_refresh;
register_displaychangelistener(ds, &dcl);
- ds->surface = qemu_create_displaysurface(ds_get_width(saved_ds),
- ds_get_height(saved_ds), 32, 4 * ds_get_width(saved_ds));
+ ds->surface = qemu_create_displaysurface(w, h, 32, 4 * w);
s->ds = ds;
s->graphic_mode = -1;
vga_update_display(s);
- ppm_save(filename, ds_get_data(ds), vga_save_w, vga_save_h,
- ds_get_linesize(ds));
+ ppm_save(filename, ds->surface);
qemu_free_displaysurface(ds->surface);
s->ds = saved_ds;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 5d06eed..f97e98f 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -202,8 +202,7 @@
uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
-int ppm_save(const char *filename, uint8_t *data,
- int w, int h, int linesize);
+int ppm_save(const char *filename, struct DisplaySurface *ds);
void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
int poffset, int w,
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5b60074..950a98c 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -975,7 +975,10 @@
}
if (s->depth == 32) {
- ppm_save(filename, s->vram, s->width, s->height, ds_get_linesize(s->ds));
+ DisplaySurface *ds = qemu_create_displaysurface_from(s->width,
+ s->height, 32, ds_get_linesize(s->ds), s->vram);
+ ppm_save(filename, ds);
+ qemu_free(ds);
}
}