Commit 9586fefefe383a9aa25ad99bde9a6b240309ca33

Authored by aliguori
1 parent b9e82a59

Fix display breakage when resizing the screen (v2) (Avi Kivity)

When the vga resolution changes, a new display surface is not allocated
immediately; instead that is deferred until the next update.  However,
if we're running without a display client attached, that won't happen
and the next bitblt is likely to cause a segfault by overflowing the
display surface.

Fix by reallocating the display immediately when the resolution changes.

Tested with (Windows|Linux) x (cirrus|std) x (curses|sdl).

Changes from v1:
 - fix segfault when switching virtual consoles with curses

Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6989 c046a42c-6fe2-441c-8c8c-71466251a162
hw/cirrus_vga.c
... ... @@ -1392,6 +1392,8 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1392 1392 break;
1393 1393 }
1394 1394  
  1395 + vga_update_resolution((VGAState *)s);
  1396 +
1395 1397 return CIRRUS_HOOK_HANDLED;
1396 1398 }
1397 1399  
... ... @@ -1419,6 +1421,7 @@ static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
1419 1421 #endif
1420 1422 }
1421 1423 s->cirrus_hidden_dac_lockindex = 0;
  1424 + vga_update_resolution((VGAState *)s);
1422 1425 }
1423 1426  
1424 1427 /***************************************
... ... @@ -1705,6 +1708,8 @@ cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1705 1708 break;
1706 1709 }
1707 1710  
  1711 + vga_update_resolution((VGAState *)s);
  1712 +
1708 1713 return CIRRUS_HOOK_HANDLED;
1709 1714 }
1710 1715  
... ... @@ -2830,6 +2835,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2830 2835 if (s->ar_flip_flop == 0) {
2831 2836 val &= 0x3f;
2832 2837 s->ar_index = val;
  2838 + vga_update_resolution((VGAState *)s);
2833 2839 } else {
2834 2840 index = s->ar_index & 0x1f;
2835 2841 switch (index) {
... ... @@ -2923,6 +2929,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2923 2929 /* can always write bit 4 of CR7 */
2924 2930 if (s->cr_index == 7)
2925 2931 s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
  2932 + vga_update_resolution((VGAState *)s);
2926 2933 return;
2927 2934 }
2928 2935 switch (s->cr_index) {
... ... @@ -2951,6 +2958,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
2951 2958 s->update_retrace_info((VGAState *) s);
2952 2959 break;
2953 2960 }
  2961 + vga_update_resolution((VGAState *)s);
2954 2962 break;
2955 2963 case 0x3ba:
2956 2964 case 0x3da:
... ... @@ -3157,7 +3165,8 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
3157 3165  
3158 3166 cirrus_update_memory_access(s);
3159 3167 /* force refresh */
3160   - s->graphic_mode = -1;
  3168 + vga_update_resolution((VGAState *)s);
  3169 + s->want_full_update = 1;
3161 3170 cirrus_update_bank_ptr(s, 0);
3162 3171 cirrus_update_bank_ptr(s, 1);
3163 3172 return 0;
... ...
hw/vga.c
... ... @@ -36,6 +36,10 @@
36 36  
37 37 //#define DEBUG_BOCHS_VBE
38 38  
  39 +#define GMODE_TEXT 0
  40 +#define GMODE_GRAPH 1
  41 +#define GMODE_BLANK 2
  42 +
39 43 /* force some bits to zero */
40 44 const uint8_t sr_mask[8] = {
41 45 0x03,
... ... @@ -393,6 +397,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
393 397 if (s->ar_flip_flop == 0) {
394 398 val &= 0x3f;
395 399 s->ar_index = val;
  400 + vga_update_resolution(s);
396 401 } else {
397 402 index = s->ar_index & 0x1f;
398 403 switch(index) {
... ... @@ -433,6 +438,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
433 438 #endif
434 439 s->sr[s->sr_index] = val & sr_mask[s->sr_index];
435 440 if (s->sr_index == 1) s->update_retrace_info(s);
  441 + vga_update_resolution(s);
436 442 break;
437 443 case 0x3c7:
438 444 s->dac_read_index = val;
... ... @@ -460,6 +466,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
460 466 printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
461 467 #endif
462 468 s->gr[s->gr_index] = val & gr_mask[s->gr_index];
  469 + vga_update_resolution(s);
463 470 break;
464 471 case 0x3b4:
465 472 case 0x3d4:
... ... @@ -475,6 +482,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
475 482 /* can always write bit 4 of CR7 */
476 483 if (s->cr_index == 7)
477 484 s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
  485 + vga_update_resolution(s);
478 486 return;
479 487 }
480 488 switch(s->cr_index) {
... ... @@ -502,6 +510,7 @@ static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
502 510 s->update_retrace_info(s);
503 511 break;
504 512 }
  513 + vga_update_resolution(s);
505 514 break;
506 515 case 0x3ba:
507 516 case 0x3da:
... ... @@ -581,11 +590,13 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
581 590 if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
582 591 s->vbe_regs[s->vbe_index] = val;
583 592 }
  593 + vga_update_resolution(s);
584 594 break;
585 595 case VBE_DISPI_INDEX_YRES:
586 596 if (val <= VBE_DISPI_MAX_YRES) {
587 597 s->vbe_regs[s->vbe_index] = val;
588 598 }
  599 + vga_update_resolution(s);
589 600 break;
590 601 case VBE_DISPI_INDEX_BPP:
591 602 if (val == 0)
... ... @@ -594,6 +605,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
594 605 val == 16 || val == 24 || val == 32) {
595 606 s->vbe_regs[s->vbe_index] = val;
596 607 }
  608 + vga_update_resolution(s);
597 609 break;
598 610 case VBE_DISPI_INDEX_BANK:
599 611 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
... ... @@ -662,6 +674,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
662 674 }
663 675 s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
664 676 s->vbe_regs[s->vbe_index] = val;
  677 + vga_update_resolution(s);
665 678 break;
666 679 case VBE_DISPI_INDEX_VIRT_WIDTH:
667 680 {
... ... @@ -682,6 +695,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
682 695 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
683 696 s->vbe_line_offset = line_offset;
684 697 }
  698 + vga_update_resolution(s);
685 699 break;
686 700 case VBE_DISPI_INDEX_X_OFFSET:
687 701 case VBE_DISPI_INDEX_Y_OFFSET:
... ... @@ -696,6 +710,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
696 710 s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
697 711 s->vbe_start_addr >>= 2;
698 712 }
  713 + vga_update_resolution(s);
699 714 break;
700 715 default:
701 716 break;
... ... @@ -1302,7 +1317,6 @@ static void vga_draw_text(VGAState *s, int full_update)
1302 1317 s->plane_updated = 0;
1303 1318 full_update = 1;
1304 1319 }
1305   - full_update |= update_basic_params(s);
1306 1320  
1307 1321 line_offset = s->line_offset;
1308 1322 s1 = s->vram_ptr + (s->start_addr * 4);
... ... @@ -1314,18 +1328,6 @@ static void vga_draw_text(VGAState *s, int full_update)
1314 1328 return;
1315 1329 }
1316 1330  
1317   - if (width != s->last_width || height != s->last_height ||
1318   - cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
1319   - s->last_scr_width = width * cw;
1320   - s->last_scr_height = height * cheight;
1321   - qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
1322   - s->last_depth = 0;
1323   - s->last_width = width;
1324   - s->last_height = height;
1325   - s->last_ch = cheight;
1326   - s->last_cw = cw;
1327   - full_update = 1;
1328   - }
1329 1331 s->rgb_to_pixel =
1330 1332 rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1331 1333 full_update |= update_palette16(s);
... ... @@ -1582,39 +1584,21 @@ static void vga_sync_dirty_bitmap(VGAState *s)
1582 1584 vga_dirty_log_start(s);
1583 1585 }
1584 1586  
1585   -/*
1586   - * graphic modes
1587   - */
1588   -static void vga_draw_graphic(VGAState *s, int full_update)
  1587 +static void vga_update_resolution_graphics(VGAState *s)
1589 1588 {
1590   - int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth;
1591   - int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
  1589 + int depth = s->get_bpp(s);
  1590 + int width, height, shift_control, double_scan;
1592 1591 int disp_width, multi_scan, multi_run;
1593   - uint8_t *d;
1594   - uint32_t v, addr1, addr;
1595   - vga_draw_line_func *vga_draw_line;
1596   -
1597   - full_update |= update_basic_params(s);
1598   -
1599   - if (!full_update)
1600   - vga_sync_dirty_bitmap(s);
1601 1592  
1602 1593 s->get_resolution(s, &width, &height);
1603 1594 disp_width = width;
1604 1595  
1605 1596 shift_control = (s->gr[0x05] >> 5) & 3;
1606 1597 double_scan = (s->cr[0x09] >> 7);
1607   - if (shift_control != 1) {
1608   - multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
1609   - } else {
1610   - /* in CGA modes, multi_scan is ignored */
1611   - /* XXX: is it correct ? */
1612   - multi_scan = double_scan;
1613   - }
1614   - multi_run = multi_scan;
  1598 +
1615 1599 if (shift_control != s->shift_control ||
1616 1600 double_scan != s->double_scan) {
1617   - full_update = 1;
  1601 + s->want_full_update = 1;
1618 1602 s->shift_control = shift_control;
1619 1603 s->double_scan = double_scan;
1620 1604 }
... ... @@ -1628,12 +1612,28 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1628 1612 disp_width <<= 1;
1629 1613 }
1630 1614 }
  1615 + disp_width = width;
  1616 +
  1617 + if (shift_control != 1) {
  1618 + multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
  1619 + } else {
  1620 + /* in CGA modes, multi_scan is ignored */
  1621 + /* XXX: is it correct ? */
  1622 + multi_scan = double_scan;
  1623 + }
  1624 +
  1625 + multi_run = multi_scan;
1631 1626  
1632   - depth = s->get_bpp(s);
1633 1627 if (s->line_offset != s->last_line_offset ||
1634 1628 disp_width != s->last_width ||
1635 1629 height != s->last_height ||
1636   - s->last_depth != depth) {
  1630 + s->last_depth != depth ||
  1631 + s->multi_run != multi_run ||
  1632 + s->multi_scan != multi_scan ||
  1633 + s->want_full_update) {
  1634 + if (s->ds->surface->pf.depth == 0) {
  1635 + goto dont_touch_display_surface;
  1636 + }
1637 1637 #if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
1638 1638 if (depth == 16 || depth == 32) {
1639 1639 #else
... ... @@ -1650,14 +1650,91 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1650 1650 } else {
1651 1651 qemu_console_resize(s->ds, disp_width, height);
1652 1652 }
  1653 + dont_touch_display_surface:
1653 1654 s->last_scr_width = disp_width;
1654 1655 s->last_scr_height = height;
1655 1656 s->last_width = disp_width;
1656 1657 s->last_height = height;
1657 1658 s->last_line_offset = s->line_offset;
1658 1659 s->last_depth = depth;
1659   - full_update = 1;
1660   - } else if (is_buffer_shared(s->ds->surface) &&
  1660 + s->multi_run = multi_run;
  1661 + s->multi_scan = multi_scan;
  1662 + s->want_full_update = 1;
  1663 + }
  1664 +}
  1665 +
  1666 +static void vga_update_resolution_text(VGAState *s)
  1667 +{
  1668 + int width, height, cw, cheight;
  1669 +
  1670 + vga_get_text_resolution(s, &width, &height, &cw, &cheight);
  1671 + if (width != s->last_width || height != s->last_height ||
  1672 + cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
  1673 + s->last_scr_width = width * cw;
  1674 + s->last_scr_height = height * cheight;
  1675 + if (s->ds->surface->pf.depth != 0) {
  1676 + qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
  1677 + } else {
  1678 + /*
  1679 + * curses expects width and height to be in character cell
  1680 + * dimensions, not pixels.
  1681 + */
  1682 + s->ds->surface->width = width;
  1683 + s->ds->surface->height = height;
  1684 + dpy_resize(s->ds);
  1685 + }
  1686 + s->last_depth = 0;
  1687 + s->last_width = width;
  1688 + s->last_height = height;
  1689 + s->last_ch = cheight;
  1690 + s->last_cw = cw;
  1691 + s->want_full_update = 1;
  1692 + }
  1693 +}
  1694 +
  1695 +void vga_update_resolution(VGAState *s)
  1696 +{
  1697 + int graphic_mode;
  1698 +
  1699 + if (!(s->ar_index & 0x20)) {
  1700 + graphic_mode = GMODE_BLANK;
  1701 + } else {
  1702 + graphic_mode = s->gr[6] & 1;
  1703 + }
  1704 + if (graphic_mode != s->graphic_mode) {
  1705 + s->graphic_mode = graphic_mode;
  1706 + s->want_full_update = 1;
  1707 + }
  1708 + s->want_full_update |= update_basic_params(s);
  1709 + switch (graphic_mode) {
  1710 + case GMODE_TEXT:
  1711 + vga_update_resolution_text(s);
  1712 + break;
  1713 + case GMODE_GRAPH:
  1714 + vga_update_resolution_graphics(s);
  1715 + break;
  1716 + }
  1717 +}
  1718 +
  1719 +/*
  1720 + * graphic modes
  1721 + */
  1722 +static void vga_draw_graphic(VGAState *s, int full_update)
  1723 +{
  1724 + int y1, y, update, linesize, y_start, mask;
  1725 + int width, height, line_offset, bwidth, bits;
  1726 + int multi_run;
  1727 + uint8_t *d;
  1728 + uint32_t v, addr1, addr;
  1729 + long page0, page1, page_min, page_max;
  1730 + vga_draw_line_func *vga_draw_line;
  1731 +
  1732 + if (!full_update)
  1733 + vga_sync_dirty_bitmap(s);
  1734 +
  1735 + s->get_resolution(s, &width, &height);
  1736 + multi_run = s->multi_run;
  1737 + if (is_buffer_shared(s->ds->surface) &&
1661 1738 (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
1662 1739 s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
1663 1740 dpy_setdata(s->ds);
... ... @@ -1666,7 +1743,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1666 1743 s->rgb_to_pixel =
1667 1744 rgb_to_pixel_dup_table[get_depth_index(s->ds)];
1668 1745  
1669   - if (shift_control == 0) {
  1746 + if (s->shift_control == 0) {
1670 1747 full_update |= update_palette16(s);
1671 1748 if (s->sr[0x01] & 8) {
1672 1749 v = VGA_DRAW_LINE4D2;
... ... @@ -1674,7 +1751,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1674 1751 v = VGA_DRAW_LINE4;
1675 1752 }
1676 1753 bits = 4;
1677   - } else if (shift_control == 1) {
  1754 + } else if (s->shift_control == 1) {
1678 1755 full_update |= update_palette16(s);
1679 1756 if (s->sr[0x01] & 8) {
1680 1757 v = VGA_DRAW_LINE2D2;
... ... @@ -1770,7 +1847,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1770 1847 if (y_start >= 0) {
1771 1848 /* flush to display */
1772 1849 dpy_update(s->ds, 0, y_start,
1773   - disp_width, y - y_start);
  1850 + s->last_width, y - y_start);
1774 1851 y_start = -1;
1775 1852 }
1776 1853 }
... ... @@ -1779,7 +1856,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1779 1856 if ((y1 & mask) == mask)
1780 1857 addr1 += line_offset;
1781 1858 y1++;
1782   - multi_run = multi_scan;
  1859 + multi_run = s->multi_scan;
1783 1860 } else {
1784 1861 multi_run--;
1785 1862 }
... ... @@ -1791,7 +1868,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1791 1868 if (y_start >= 0) {
1792 1869 /* flush to display */
1793 1870 dpy_update(s->ds, 0, y_start,
1794   - disp_width, y - y_start);
  1871 + s->last_width, y - y_start);
1795 1872 }
1796 1873 /* reset modified pages */
1797 1874 if (page_max != -1) {
... ... @@ -1828,29 +1905,17 @@ static void vga_draw_blank(VGAState *s, int full_update)
1828 1905 s->last_scr_width, s->last_scr_height);
1829 1906 }
1830 1907  
1831   -#define GMODE_TEXT 0
1832   -#define GMODE_GRAPH 1
1833   -#define GMODE_BLANK 2
1834   -
1835 1908 static void vga_update_display(void *opaque)
1836 1909 {
1837 1910 VGAState *s = (VGAState *)opaque;
1838   - int full_update, graphic_mode;
  1911 + int full_update;
1839 1912  
1840 1913 if (ds_get_bits_per_pixel(s->ds) == 0) {
1841 1914 /* nothing to do */
1842 1915 } else {
1843   - full_update = 0;
1844   - if (!(s->ar_index & 0x20)) {
1845   - graphic_mode = GMODE_BLANK;
1846   - } else {
1847   - graphic_mode = s->gr[6] & 1;
1848   - }
1849   - if (graphic_mode != s->graphic_mode) {
1850   - s->graphic_mode = graphic_mode;
1851   - full_update = 1;
1852   - }
1853   - switch(graphic_mode) {
  1916 + full_update = s->want_full_update;
  1917 + s->want_full_update = 0;
  1918 + switch(s->graphic_mode) {
1854 1919 case GMODE_TEXT:
1855 1920 vga_draw_text(s, full_update);
1856 1921 break;
... ... @@ -1870,8 +1935,8 @@ static void vga_invalidate_display(void *opaque)
1870 1935 {
1871 1936 VGAState *s = (VGAState *)opaque;
1872 1937  
1873   - s->last_width = -1;
1874   - s->last_height = -1;
  1938 + vga_update_resolution(s);
  1939 + s->want_full_update = 1;
1875 1940 }
1876 1941  
1877 1942 void vga_reset(void *opaque)
... ... @@ -1915,7 +1980,6 @@ void vga_reset(void *opaque)
1915 1980 s->vbe_bank_mask = (s->vram_size >> 16) - 1;
1916 1981 #endif
1917 1982 memset(s->font_offsets, '\0', sizeof(s->font_offsets));
1918   - s->graphic_mode = -1; /* force full update */
1919 1983 s->shift_control = 0;
1920 1984 s->double_scan = 0;
1921 1985 s->line_offset = 0;
... ... @@ -1941,6 +2005,7 @@ void vga_reset(void *opaque)
1941 2005 memset(&s->retrace_info, 0, sizeof (s->retrace_info));
1942 2006 break;
1943 2007 }
  2008 + vga_update_resolution(s);
1944 2009 }
1945 2010  
1946 2011 #define TEXTMODE_X(x) ((x) % width)
... ... @@ -1952,50 +2017,28 @@ void vga_reset(void *opaque)
1952 2017 static void vga_update_text(void *opaque, console_ch_t *chardata)
1953 2018 {
1954 2019 VGAState *s = (VGAState *) opaque;
1955   - int graphic_mode, i, cursor_offset, cursor_visible;
  2020 + int i, cursor_offset, cursor_visible;
1956 2021 int cw, cheight, width, height, size, c_min, c_max;
1957 2022 uint32_t *src;
1958 2023 console_ch_t *dst, val;
1959 2024 char msg_buffer[80];
1960   - int full_update = 0;
1961   -
1962   - if (!(s->ar_index & 0x20)) {
1963   - graphic_mode = GMODE_BLANK;
1964   - } else {
1965   - graphic_mode = s->gr[6] & 1;
1966   - }
1967   - if (graphic_mode != s->graphic_mode) {
1968   - s->graphic_mode = graphic_mode;
1969   - full_update = 1;
1970   - }
1971   - if (s->last_width == -1) {
1972   - s->last_width = 0;
1973   - full_update = 1;
1974   - }
  2025 + int full_update = s->want_full_update;
1975 2026  
1976   - switch (graphic_mode) {
  2027 + s->want_full_update = 0;
  2028 + switch (s->graphic_mode) {
1977 2029 case GMODE_TEXT:
1978 2030 /* TODO: update palette */
1979   - full_update |= update_basic_params(s);
1980 2031  
1981   - /* total width & height */
1982   - cheight = (s->cr[9] & 0x1f) + 1;
1983   - cw = 8;
1984   - if (!(s->sr[1] & 0x01))
1985   - cw = 9;
1986   - if (s->sr[1] & 0x08)
1987   - cw = 16; /* NOTE: no 18 pixel wide */
1988   - width = (s->cr[0x01] + 1);
1989   - if (s->cr[0x06] == 100) {
1990   - /* ugly hack for CGA 160x100x16 - explain me the logic */
1991   - height = 100;
1992   - } else {
1993   - height = s->cr[0x12] |
1994   - ((s->cr[0x07] & 0x02) << 7) |
1995   - ((s->cr[0x07] & 0x40) << 3);
1996   - height = (height + 1) / cheight;
  2032 + vga_get_text_resolution(s, &width, &height, &cw, &cheight);
  2033 +
  2034 + if (s->ds->surface->width != width
  2035 + || s->ds->surface->height != height) {
  2036 + s->ds->surface->width = width;
  2037 + s->ds->surface->height = height;
  2038 + dpy_resize(s->ds);
1997 2039 }
1998 2040  
  2041 + /* total width & height */
1999 2042 size = (height * width);
2000 2043 if (size > CH_ATTR_SIZE) {
2001 2044 if (!full_update)
... ... @@ -2006,20 +2049,6 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
2006 2049 break;
2007 2050 }
2008 2051  
2009   - if (width != s->last_width || height != s->last_height ||
2010   - cw != s->last_cw || cheight != s->last_ch) {
2011   - s->last_scr_width = width * cw;
2012   - s->last_scr_height = height * cheight;
2013   - s->ds->surface->width = width;
2014   - s->ds->surface->height = height;
2015   - dpy_resize(s->ds);
2016   - s->last_width = width;
2017   - s->last_height = height;
2018   - s->last_ch = cheight;
2019   - s->last_cw = cw;
2020   - full_update = 1;
2021   - }
2022   -
2023 2052 /* Update "hardware" cursor */
2024 2053 cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
2025 2054 if (cursor_offset != s->cursor_offset ||
... ... @@ -2218,7 +2247,8 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
2218 2247 #endif
2219 2248  
2220 2249 /* force refresh */
2221   - s->graphic_mode = -1;
  2250 + vga_update_resolution(s);
  2251 + s->want_full_update = 1;
2222 2252 return 0;
2223 2253 }
2224 2254  
... ... @@ -2641,7 +2671,8 @@ static void vga_screen_dump_common(VGAState *s, const char *filename,
2641 2671 ds->surface = qemu_create_displaysurface(ds, w, h);
2642 2672  
2643 2673 s->ds = ds;
2644   - s->graphic_mode = -1;
  2674 + vga_update_resolution(s);
  2675 + s->want_full_update = 1;
2645 2676 vga_update_display(s);
2646 2677  
2647 2678 ppm_save(filename, ds->surface);
... ... @@ -2672,10 +2703,16 @@ static void vga_screen_dump(void *opaque, const char *filename)
2672 2703 {
2673 2704 VGAState *s = (VGAState *)opaque;
2674 2705  
2675   - if (!(s->ar_index & 0x20))
2676   - vga_screen_dump_blank(s, filename);
2677   - else if (s->gr[6] & 1)
2678   - vga_screen_dump_graphic(s, filename);
2679   - else
  2706 + switch (s->graphic_mode) {
  2707 + case GMODE_TEXT:
2680 2708 vga_screen_dump_text(s, filename);
  2709 + break;
  2710 + case GMODE_GRAPH:
  2711 + vga_screen_dump_graphic(s, filename);
  2712 + break;
  2713 + case GMODE_BLANK:
  2714 + default:
  2715 + vga_screen_dump_blank(s, filename);
  2716 + break;
  2717 + }
2681 2718 }
... ...
hw/vga_int.h
... ... @@ -147,8 +147,11 @@ typedef void (* vga_update_retrace_info_fn)(struct VGAState *s);
147 147 DisplayState *ds; \
148 148 uint32_t font_offsets[2]; \
149 149 int graphic_mode; \
  150 + int want_full_update; \
150 151 uint8_t shift_control; \
151 152 uint8_t double_scan; \
  153 + uint8_t multi_run; \
  154 + uint8_t multi_scan; \
152 155 uint32_t line_offset; \
153 156 uint32_t line_compare; \
154 157 uint32_t start_addr; \
... ... @@ -195,6 +198,7 @@ void vga_common_init(VGAState *s, uint8_t *vga_ram_base,
195 198 ram_addr_t vga_ram_offset, int vga_ram_size);
196 199 void vga_init(VGAState *s);
197 200 void vga_reset(void *s);
  201 +void vga_update_resolution(VGAState *s);
198 202  
199 203 void vga_dirty_log_start(VGAState *s);
200 204 void vga_dirty_log_stop(VGAState *s);
... ...