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 | 737 | } |
738 | 738 | |
739 | 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 | 742 | VGAState *s = &vga_state; |
743 | 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 | 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 | 870 | vga_mem_writeb(addr, val & 0xff, vaddr); |
871 | 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 | 876 | vga_mem_writeb(addr, val & 0xff, vaddr); |
877 | 877 | vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); |
... | ... | @@ -1523,7 +1523,23 @@ void vga_update_display(void) |
1523 | 1523 | |
1524 | 1524 | if (s->ds->depth == 0) { |
1525 | 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 | 1543 | full_update = 0; |
1528 | 1544 | graphic_mode = s->gr[6] & 1; |
1529 | 1545 | if (graphic_mode != s->graphic_mode) { |
... | ... | @@ -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 | 1558 | memset(s, 0, sizeof(VGAState)); |
1543 | 1559 | #ifdef CONFIG_S3VGA |
... | ... | @@ -1550,13 +1566,13 @@ void vga_reset(VGAState *s) |
1550 | 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 | 1570 | vga_mem_readb, |
1555 | 1571 | vga_mem_readw, |
1556 | 1572 | vga_mem_readl, |
1557 | 1573 | }; |
1558 | 1574 | |
1559 | -CPUWriteMemoryFunc *vga_mem_write[3] = { | |
1575 | +static CPUWriteMemoryFunc *vga_mem_write[3] = { | |
1560 | 1576 | vga_mem_writeb, |
1561 | 1577 | vga_mem_writew, |
1562 | 1578 | vga_mem_writel, |
... | ... | @@ -1593,22 +1609,6 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, |
1593 | 1609 | |
1594 | 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 | 1612 | s->vram_ptr = vga_ram_base; |
1613 | 1613 | s->vram_offset = vga_ram_offset; |
1614 | 1614 | s->vram_size = vga_ram_size; |
... | ... | @@ -1652,3 +1652,84 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, |
1652 | 1652 | #endif |
1653 | 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 | 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 | 257 | static term_cmd_t term_cmds[] = { |
249 | 258 | { "help|?", do_help, |
250 | 259 | "[cmd]", "show the help" }, |
... | ... | @@ -258,6 +267,8 @@ static term_cmd_t term_cmds[] = { |
258 | 267 | "[-f] device", "eject a removable media (use -f to force it)" }, |
259 | 268 | { "change", do_change, |
260 | 269 | "device filename", "change a removable media" }, |
270 | + { "screendump", do_screen_dump, | |
271 | + "filename", "save screen into PPM image 'filename'" }, | |
261 | 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 | 136 | int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, |
137 | 137 | unsigned long vga_ram_offset, int vga_ram_size); |
138 | 138 | void vga_update_display(void); |
139 | +void vga_screen_dump(const char *filename); | |
139 | 140 | |
140 | 141 | /* sdl.c */ |
141 | 142 | void sdl_display_init(DisplayState *ds); | ... | ... |