]> git.proxmox.com Git - mirror_qemu.git/commitdiff
device independent VGA screen dump
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 17 Mar 2004 23:17:16 +0000 (23:17 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 17 Mar 2004 23:17:16 +0000 (23:17 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@668 c046a42c-6fe2-441c-8c8c-71466251a162

hw/vga.c
monitor.c
vl.h

index 452de61d075795e232d9bd7bd3c0048a5b60b0ed..5d2acc85fd4e87291a8b10d0e3de1996914a4780 100644 (file)
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -737,7 +737,7 @@ static uint32_t vga_mem_readl(uint32_t addr)
 }
 
 /* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
+static void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
     VGAState *s = &vga_state;
     int memory_map_mode, plane, write_mode, b, func_select;
@@ -865,13 +865,13 @@ void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
     }
 }
 
-void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
+static void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
     vga_mem_writeb(addr, val & 0xff, vaddr);
     vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr);
 }
 
-void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
+static void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
     vga_mem_writeb(addr, val & 0xff, vaddr);
     vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr);
@@ -1523,7 +1523,23 @@ void vga_update_display(void)
 
     if (s->ds->depth == 0) {
         /* nothing to do */
-   } else {
+    } else {
+        switch(s->ds->depth) {
+        case 8:
+            s->rgb_to_pixel = rgb_to_pixel8_dup;
+            break;
+        case 15:
+            s->rgb_to_pixel = rgb_to_pixel15_dup;
+            break;
+        default:
+        case 16:
+            s->rgb_to_pixel = rgb_to_pixel16_dup;
+            break;
+        case 32:
+            s->rgb_to_pixel = rgb_to_pixel32_dup;
+            break;
+        }
+        
         full_update = 0;
         graphic_mode = s->gr[6] & 1;
         if (graphic_mode != s->graphic_mode) {
@@ -1537,7 +1553,7 @@ void vga_update_display(void)
     }
 }
 
-void vga_reset(VGAState *s)
+static void vga_reset(VGAState *s)
 {
     memset(s, 0, sizeof(VGAState));
 #ifdef CONFIG_S3VGA
@@ -1550,13 +1566,13 @@ void vga_reset(VGAState *s)
     s->graphic_mode = -1; /* force full update */
 }
 
-CPUReadMemoryFunc *vga_mem_read[3] = {
+static CPUReadMemoryFunc *vga_mem_read[3] = {
     vga_mem_readb,
     vga_mem_readw,
     vga_mem_readl,
 };
 
-CPUWriteMemoryFunc *vga_mem_write[3] = {
+static CPUWriteMemoryFunc *vga_mem_write[3] = {
     vga_mem_writeb,
     vga_mem_writew,
     vga_mem_writel,
@@ -1593,22 +1609,6 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base,
 
     vga_reset(s);
 
-    switch(ds->depth) {
-    case 8:
-        s->rgb_to_pixel = rgb_to_pixel8_dup;
-        break;
-    case 15:
-        s->rgb_to_pixel = rgb_to_pixel15_dup;
-        break;
-    default:
-    case 16:
-        s->rgb_to_pixel = rgb_to_pixel16_dup;
-        break;
-    case 32:
-        s->rgb_to_pixel = rgb_to_pixel32_dup;
-        break;
-    }
-
     s->vram_ptr = vga_ram_base;
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
@@ -1652,3 +1652,84 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base,
 #endif
     return 0;
 }
+
+/********************************************************/
+/* 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)
+{
+}
+
+static void vga_save_dpy_resize(DisplayState *s, int w, int h)
+{
+    s->linesize = w * 4;
+    s->data = qemu_malloc(h * s->linesize);
+    vga_save_w = w;
+    vga_save_h = h;
+}
+
+static void vga_save_dpy_refresh(DisplayState *s)
+{
+}
+
+static int ppm_save(const char *filename, uint8_t *data, 
+                    int w, int h, int linesize)
+{
+    FILE *f;
+    uint8_t *d, *d1;
+    unsigned int v;
+    int y, x;
+
+    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++) {
+        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;
+        }
+        d1 += linesize;
+    }
+    fclose(f);
+    return 0;
+}
+
+/* save the vga display in a PPM image even if no display is
+   available */
+void vga_screen_dump(const char *filename)
+{
+    VGAState *s = &vga_state;
+    DisplayState *saved_ds, ds1, *ds = &ds1;
+    
+    /* XXX: this is a little hackish */
+    s->last_width = -1;
+    s->last_height = -1;
+    saved_ds = s->ds;
+
+    memset(ds, 0, sizeof(DisplayState));
+    ds->dpy_update = vga_save_dpy_update;
+    ds->dpy_resize = vga_save_dpy_resize;
+    ds->dpy_refresh = vga_save_dpy_refresh;
+    ds->depth = 32;
+
+    s->ds = ds;
+    s->graphic_mode = -1;
+    vga_update_display();
+    
+    if (ds->data) {
+        ppm_save(filename, ds->data, vga_save_w, vga_save_h, 
+                 s->ds->linesize);
+        qemu_free(ds->data);
+    }
+    s->ds = saved_ds;
+}
index 633b8989214b74e3e4301835ed768bb6f5c53eed..195a0b0071f63f62ef2264eb9b750cf2bf5f2f99 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -245,6 +245,15 @@ static void do_change(int argc, const char **argv)
     bdrv_open(bs, argv[2], 0);
 }
 
+static void do_screen_dump(int argc, const char **argv)
+{
+    if (argc != 2) {
+        help_cmd(argv[0]);
+        return;
+    }
+    vga_screen_dump(argv[1]);
+}
+
 static term_cmd_t term_cmds[] = {
     { "help|?", do_help, 
       "[cmd]", "show the help" },
@@ -258,6 +267,8 @@ static term_cmd_t term_cmds[] = {
       "[-f] device", "eject a removable media (use -f to force it)" },
     { "change", do_change,
       "device filename", "change a removable media" },
+    { "screendump", do_screen_dump, 
+      "filename", "save screen into PPM image 'filename'" },
     { NULL, NULL, },
 };
 
diff --git a/vl.h b/vl.h
index 50e160987b8b8a6084059bc2c03182d878468429..11d7aba4117c4c254b5ab850f2e4d00edc7962c8 100644 (file)
--- a/vl.h
+++ b/vl.h
@@ -136,6 +136,7 @@ static inline void dpy_resize(DisplayState *s, int w, int h)
 int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, 
                    unsigned long vga_ram_offset, int vga_ram_size);
 void vga_update_display(void);
+void vga_screen_dump(const char *filename);
 
 /* sdl.c */
 void sdl_display_init(DisplayState *ds);