Commit 59a983b921e8318ae8da357aacd496c3ab5bbc5b
1 parent
4e463d8d
device independent VGA screen dump
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@668 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
116 additions
and
23 deletions
hw/vga.c
@@ -737,7 +737,7 @@ static uint32_t vga_mem_readl(uint32_t addr) | @@ -737,7 +737,7 @@ static uint32_t vga_mem_readl(uint32_t addr) | ||
737 | } | 737 | } |
738 | 738 | ||
739 | /* called for accesses between 0xa0000 and 0xc0000 */ | 739 | /* called for accesses between 0xa0000 and 0xc0000 */ |
740 | -void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) | 740 | +static void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) |
741 | { | 741 | { |
742 | VGAState *s = &vga_state; | 742 | VGAState *s = &vga_state; |
743 | int memory_map_mode, plane, write_mode, b, func_select; | 743 | 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) | @@ -865,13 +865,13 @@ void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) | ||
865 | } | 865 | } |
866 | } | 866 | } |
867 | 867 | ||
868 | -void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr) | 868 | +static void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr) |
869 | { | 869 | { |
870 | vga_mem_writeb(addr, val & 0xff, vaddr); | 870 | vga_mem_writeb(addr, val & 0xff, vaddr); |
871 | vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); | 871 | vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); |
872 | } | 872 | } |
873 | 873 | ||
874 | -void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr) | 874 | +static void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr) |
875 | { | 875 | { |
876 | vga_mem_writeb(addr, val & 0xff, vaddr); | 876 | vga_mem_writeb(addr, val & 0xff, vaddr); |
877 | vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); | 877 | vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); |
@@ -1523,7 +1523,23 @@ void vga_update_display(void) | @@ -1523,7 +1523,23 @@ void vga_update_display(void) | ||
1523 | 1523 | ||
1524 | if (s->ds->depth == 0) { | 1524 | if (s->ds->depth == 0) { |
1525 | /* nothing to do */ | 1525 | /* nothing to do */ |
1526 | - } else { | 1526 | + } else { |
1527 | + switch(s->ds->depth) { | ||
1528 | + case 8: | ||
1529 | + s->rgb_to_pixel = rgb_to_pixel8_dup; | ||
1530 | + break; | ||
1531 | + case 15: | ||
1532 | + s->rgb_to_pixel = rgb_to_pixel15_dup; | ||
1533 | + break; | ||
1534 | + default: | ||
1535 | + case 16: | ||
1536 | + s->rgb_to_pixel = rgb_to_pixel16_dup; | ||
1537 | + break; | ||
1538 | + case 32: | ||
1539 | + s->rgb_to_pixel = rgb_to_pixel32_dup; | ||
1540 | + break; | ||
1541 | + } | ||
1542 | + | ||
1527 | full_update = 0; | 1543 | full_update = 0; |
1528 | graphic_mode = s->gr[6] & 1; | 1544 | graphic_mode = s->gr[6] & 1; |
1529 | if (graphic_mode != s->graphic_mode) { | 1545 | if (graphic_mode != s->graphic_mode) { |
@@ -1537,7 +1553,7 @@ void vga_update_display(void) | @@ -1537,7 +1553,7 @@ void vga_update_display(void) | ||
1537 | } | 1553 | } |
1538 | } | 1554 | } |
1539 | 1555 | ||
1540 | -void vga_reset(VGAState *s) | 1556 | +static void vga_reset(VGAState *s) |
1541 | { | 1557 | { |
1542 | memset(s, 0, sizeof(VGAState)); | 1558 | memset(s, 0, sizeof(VGAState)); |
1543 | #ifdef CONFIG_S3VGA | 1559 | #ifdef CONFIG_S3VGA |
@@ -1550,13 +1566,13 @@ void vga_reset(VGAState *s) | @@ -1550,13 +1566,13 @@ void vga_reset(VGAState *s) | ||
1550 | s->graphic_mode = -1; /* force full update */ | 1566 | s->graphic_mode = -1; /* force full update */ |
1551 | } | 1567 | } |
1552 | 1568 | ||
1553 | -CPUReadMemoryFunc *vga_mem_read[3] = { | 1569 | +static CPUReadMemoryFunc *vga_mem_read[3] = { |
1554 | vga_mem_readb, | 1570 | vga_mem_readb, |
1555 | vga_mem_readw, | 1571 | vga_mem_readw, |
1556 | vga_mem_readl, | 1572 | vga_mem_readl, |
1557 | }; | 1573 | }; |
1558 | 1574 | ||
1559 | -CPUWriteMemoryFunc *vga_mem_write[3] = { | 1575 | +static CPUWriteMemoryFunc *vga_mem_write[3] = { |
1560 | vga_mem_writeb, | 1576 | vga_mem_writeb, |
1561 | vga_mem_writew, | 1577 | vga_mem_writew, |
1562 | vga_mem_writel, | 1578 | vga_mem_writel, |
@@ -1593,22 +1609,6 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | @@ -1593,22 +1609,6 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | ||
1593 | 1609 | ||
1594 | vga_reset(s); | 1610 | vga_reset(s); |
1595 | 1611 | ||
1596 | - switch(ds->depth) { | ||
1597 | - case 8: | ||
1598 | - s->rgb_to_pixel = rgb_to_pixel8_dup; | ||
1599 | - break; | ||
1600 | - case 15: | ||
1601 | - s->rgb_to_pixel = rgb_to_pixel15_dup; | ||
1602 | - break; | ||
1603 | - default: | ||
1604 | - case 16: | ||
1605 | - s->rgb_to_pixel = rgb_to_pixel16_dup; | ||
1606 | - break; | ||
1607 | - case 32: | ||
1608 | - s->rgb_to_pixel = rgb_to_pixel32_dup; | ||
1609 | - break; | ||
1610 | - } | ||
1611 | - | ||
1612 | s->vram_ptr = vga_ram_base; | 1612 | s->vram_ptr = vga_ram_base; |
1613 | s->vram_offset = vga_ram_offset; | 1613 | s->vram_offset = vga_ram_offset; |
1614 | s->vram_size = vga_ram_size; | 1614 | s->vram_size = vga_ram_size; |
@@ -1652,3 +1652,84 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | @@ -1652,3 +1652,84 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | ||
1652 | #endif | 1652 | #endif |
1653 | return 0; | 1653 | return 0; |
1654 | } | 1654 | } |
1655 | + | ||
1656 | +/********************************************************/ | ||
1657 | +/* vga screen dump */ | ||
1658 | + | ||
1659 | +static int vga_save_w, vga_save_h; | ||
1660 | + | ||
1661 | +static void vga_save_dpy_update(DisplayState *s, | ||
1662 | + int x, int y, int w, int h) | ||
1663 | +{ | ||
1664 | +} | ||
1665 | + | ||
1666 | +static void vga_save_dpy_resize(DisplayState *s, int w, int h) | ||
1667 | +{ | ||
1668 | + s->linesize = w * 4; | ||
1669 | + s->data = qemu_malloc(h * s->linesize); | ||
1670 | + vga_save_w = w; | ||
1671 | + vga_save_h = h; | ||
1672 | +} | ||
1673 | + | ||
1674 | +static void vga_save_dpy_refresh(DisplayState *s) | ||
1675 | +{ | ||
1676 | +} | ||
1677 | + | ||
1678 | +static int ppm_save(const char *filename, uint8_t *data, | ||
1679 | + int w, int h, int linesize) | ||
1680 | +{ | ||
1681 | + FILE *f; | ||
1682 | + uint8_t *d, *d1; | ||
1683 | + unsigned int v; | ||
1684 | + int y, x; | ||
1685 | + | ||
1686 | + f = fopen(filename, "wb"); | ||
1687 | + if (!f) | ||
1688 | + return -1; | ||
1689 | + fprintf(f, "P6\n%d %d\n%d\n", | ||
1690 | + w, h, 255); | ||
1691 | + d1 = data; | ||
1692 | + for(y = 0; y < h; y++) { | ||
1693 | + d = d1; | ||
1694 | + for(x = 0; x < w; x++) { | ||
1695 | + v = *(uint32_t *)d; | ||
1696 | + fputc((v >> 16) & 0xff, f); | ||
1697 | + fputc((v >> 8) & 0xff, f); | ||
1698 | + fputc((v) & 0xff, f); | ||
1699 | + d += 4; | ||
1700 | + } | ||
1701 | + d1 += linesize; | ||
1702 | + } | ||
1703 | + fclose(f); | ||
1704 | + return 0; | ||
1705 | +} | ||
1706 | + | ||
1707 | +/* save the vga display in a PPM image even if no display is | ||
1708 | + available */ | ||
1709 | +void vga_screen_dump(const char *filename) | ||
1710 | +{ | ||
1711 | + VGAState *s = &vga_state; | ||
1712 | + DisplayState *saved_ds, ds1, *ds = &ds1; | ||
1713 | + | ||
1714 | + /* XXX: this is a little hackish */ | ||
1715 | + s->last_width = -1; | ||
1716 | + s->last_height = -1; | ||
1717 | + saved_ds = s->ds; | ||
1718 | + | ||
1719 | + memset(ds, 0, sizeof(DisplayState)); | ||
1720 | + ds->dpy_update = vga_save_dpy_update; | ||
1721 | + ds->dpy_resize = vga_save_dpy_resize; | ||
1722 | + ds->dpy_refresh = vga_save_dpy_refresh; | ||
1723 | + ds->depth = 32; | ||
1724 | + | ||
1725 | + s->ds = ds; | ||
1726 | + s->graphic_mode = -1; | ||
1727 | + vga_update_display(); | ||
1728 | + | ||
1729 | + if (ds->data) { | ||
1730 | + ppm_save(filename, ds->data, vga_save_w, vga_save_h, | ||
1731 | + s->ds->linesize); | ||
1732 | + qemu_free(ds->data); | ||
1733 | + } | ||
1734 | + s->ds = saved_ds; | ||
1735 | +} |
monitor.c
@@ -245,6 +245,15 @@ static void do_change(int argc, const char **argv) | @@ -245,6 +245,15 @@ static void do_change(int argc, const char **argv) | ||
245 | bdrv_open(bs, argv[2], 0); | 245 | bdrv_open(bs, argv[2], 0); |
246 | } | 246 | } |
247 | 247 | ||
248 | +static void do_screen_dump(int argc, const char **argv) | ||
249 | +{ | ||
250 | + if (argc != 2) { | ||
251 | + help_cmd(argv[0]); | ||
252 | + return; | ||
253 | + } | ||
254 | + vga_screen_dump(argv[1]); | ||
255 | +} | ||
256 | + | ||
248 | static term_cmd_t term_cmds[] = { | 257 | static term_cmd_t term_cmds[] = { |
249 | { "help|?", do_help, | 258 | { "help|?", do_help, |
250 | "[cmd]", "show the help" }, | 259 | "[cmd]", "show the help" }, |
@@ -258,6 +267,8 @@ static term_cmd_t term_cmds[] = { | @@ -258,6 +267,8 @@ static term_cmd_t term_cmds[] = { | ||
258 | "[-f] device", "eject a removable media (use -f to force it)" }, | 267 | "[-f] device", "eject a removable media (use -f to force it)" }, |
259 | { "change", do_change, | 268 | { "change", do_change, |
260 | "device filename", "change a removable media" }, | 269 | "device filename", "change a removable media" }, |
270 | + { "screendump", do_screen_dump, | ||
271 | + "filename", "save screen into PPM image 'filename'" }, | ||
261 | { NULL, NULL, }, | 272 | { NULL, NULL, }, |
262 | }; | 273 | }; |
263 | 274 |
vl.h
@@ -136,6 +136,7 @@ static inline void dpy_resize(DisplayState *s, int w, int h) | @@ -136,6 +136,7 @@ static inline void dpy_resize(DisplayState *s, int w, int h) | ||
136 | int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, | 136 | int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, |
137 | unsigned long vga_ram_offset, int vga_ram_size); | 137 | unsigned long vga_ram_offset, int vga_ram_size); |
138 | void vga_update_display(void); | 138 | void vga_update_display(void); |
139 | +void vga_screen_dump(const char *filename); | ||
139 | 140 | ||
140 | /* sdl.c */ | 141 | /* sdl.c */ |
141 | void sdl_display_init(DisplayState *ds); | 142 | void sdl_display_init(DisplayState *ds); |