qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] fix screendump
Date: Fri, 16 Jan 2009 17:59:08 +0000	[thread overview]
Message-ID: <4970CAEC.9060702@eu.citrix.com> (raw)

Hi all,
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>

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 @@ int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
 /********************************************************/
 /* 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 @@ static void vga_save_dpy_refresh(DisplayState *s)
 {
 }
 
-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 @@ static void vga_screen_dump_common(VGAState *s, const char *filename,
     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 @@ void vga_dirty_log_stop(VGAState *s);
 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 @@ static void vmsvga_screen_dump(void *opaque, const char *filename)
     }
 
     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);
     }
 }
 

             reply	other threads:[~2009-01-16 18:00 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-16 17:59 Stefano Stabellini [this message]
2009-01-16 18:23 ` [Qemu-devel] [PATCH] fix screendump Anthony Liguori
2009-01-16 19:08 ` Anthony Liguori
2009-01-19 11:22   ` Stefano Stabellini
  -- strict thread matches above, loose matches on Subject: below --
2012-03-01  7:34 Gerd Hoffmann
2012-03-01 10:45 ` Alon Levy
2012-03-01 11:06 ` Avi Kivity
2012-03-19 16:41 ` Jan Kiszka
2012-03-24 16:11 ` Blue Swirl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4970CAEC.9060702@eu.citrix.com \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).