aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2009-08-11 16:18:07 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-08-24 08:01:39 -0500
commit04a52b412037420e01276c92cf672dbab7f78399 (patch)
tree9399c407df9f3cada217e5fa706bc0eb9daab9d5 /hw
parentb6f6d0e2f83e52f21a4dce9476d794ed279b900e (diff)
make vga screen_dump use DisplayState properly
Hi all, currently the vga screen_dump code doesn't use the DisplayState interface properly and tries to replace it temporarily while taking the screenshot. A better approach is to register a DisplayChangeListener, call vga_hw_update, and finally write the ppm in the next call from dpy_update. Testing is appreciated. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/vga.c90
1 files changed, 21 insertions, 69 deletions
diff --git a/hw/vga.c b/hw/vga.c
index 4a0f197593..3882f20c0a 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -150,6 +150,8 @@ static uint16_t expand2[256];
static uint8_t expand4to8[16];
static void vga_screen_dump(void *opaque, const char *filename);
+static char *screen_dump_filename;
+static DisplayChangeListener *screen_dump_dcl;
static void vga_dumb_update_retrace_info(VGAState *s)
{
@@ -2548,9 +2550,13 @@ device_init(vga_register);
/********************************************************/
/* vga screen dump */
-static void vga_save_dpy_update(DisplayState *s,
+static void vga_save_dpy_update(DisplayState *ds,
int x, int y, int w, int h)
{
+ if (screen_dump_filename) {
+ ppm_save(screen_dump_filename, ds->surface);
+ screen_dump_filename = NULL;
+ }
}
static void vga_save_dpy_resize(DisplayState *s)
@@ -2599,70 +2605,16 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
return 0;
}
-static void vga_screen_dump_blank(VGAState *s, const char *filename)
-{
- FILE *f;
- unsigned int y, x, w, h;
- unsigned char blank_sample[3] = { 0, 0, 0 };
-
- w = s->last_scr_width;
- h = s->last_scr_height;
-
- f = fopen(filename, "wb");
- if (!f)
- return;
- fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- fwrite(blank_sample, 3, 1, f);
- }
- }
- fclose(f);
-}
-
-static void vga_screen_dump_common(VGAState *s, const char *filename,
- int w, int h)
-{
- DisplayState *saved_ds, ds1, *ds = &ds1;
- DisplayChangeListener dcl;
-
- /* XXX: this is a little hackish */
- vga_invalidate_display(s);
- saved_ds = s->ds;
-
- memset(ds, 0, sizeof(DisplayState));
- memset(&dcl, 0, sizeof(DisplayChangeListener));
- dcl.dpy_update = vga_save_dpy_update;
- dcl.dpy_resize = vga_save_dpy_resize;
- dcl.dpy_refresh = vga_save_dpy_refresh;
- register_displaychangelistener(ds, &dcl);
- ds->allocator = &default_allocator;
- ds->surface = qemu_create_displaysurface(ds, w, h);
-
- s->ds = ds;
- s->graphic_mode = -1;
- vga_update_display(s);
-
- ppm_save(filename, ds->surface);
-
- qemu_free_displaysurface(ds);
- s->ds = saved_ds;
-}
-
-static void vga_screen_dump_graphic(VGAState *s, const char *filename)
+static DisplayChangeListener* vga_screen_dump_init(DisplayState *ds)
{
- int w, h;
+ DisplayChangeListener *dcl;
- s->get_resolution(s, &w, &h);
- vga_screen_dump_common(s, filename, w, h);
-}
-
-static void vga_screen_dump_text(VGAState *s, const char *filename)
-{
- int w, h, cwidth, cheight;
-
- vga_get_text_resolution(s, &w, &h, &cwidth, &cheight);
- vga_screen_dump_common(s, filename, w * cwidth, h * cheight);
+ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+ dcl->dpy_update = vga_save_dpy_update;
+ dcl->dpy_resize = vga_save_dpy_resize;
+ dcl->dpy_refresh = vga_save_dpy_refresh;
+ register_displaychangelistener(ds, dcl);
+ return dcl;
}
/* save the vga display in a PPM image even if no display is
@@ -2671,11 +2623,11 @@ static void vga_screen_dump(void *opaque, const char *filename)
{
VGAState *s = (VGAState *)opaque;
- if (!(s->ar_index & 0x20))
- vga_screen_dump_blank(s, filename);
- else if (s->gr[6] & 1)
- vga_screen_dump_graphic(s, filename);
- else
- vga_screen_dump_text(s, filename);
+ if (!screen_dump_dcl)
+ screen_dump_dcl = vga_screen_dump_init(s->ds);
+
+ screen_dump_filename = (char *)filename;
vga_invalidate_display(s);
+ vga_hw_update();
}
+