Commit a8aa669ba406a0d6530f48e0c87a358ba614aa95
1 parent
a5082316
generic hardware cursor support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@903 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
115 additions
and
12 deletions
hw/vga.c
| ... | ... | @@ -852,14 +852,6 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign |
| 852 | 852 | #define DEPTH 32 |
| 853 | 853 | #include "vga_template.h" |
| 854 | 854 | |
| 855 | -static inline int c6_to_8(int v) | |
| 856 | -{ | |
| 857 | - int b; | |
| 858 | - v &= 0x3f; | |
| 859 | - b = v & 1; | |
| 860 | - return (v << 2) | (b << 1) | b; | |
| 861 | -} | |
| 862 | - | |
| 863 | 855 | static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b) |
| 864 | 856 | { |
| 865 | 857 | unsigned int col; |
| ... | ... | @@ -1309,11 +1301,20 @@ static int vga_get_bpp(VGAState *s) |
| 1309 | 1301 | return ret; |
| 1310 | 1302 | } |
| 1311 | 1303 | |
| 1304 | +void vga_invalidate_scanlines(VGAState *s, int y1, int y2) | |
| 1305 | +{ | |
| 1306 | + int y; | |
| 1307 | + if (y1 >= VGA_MAX_HEIGHT) | |
| 1308 | + return; | |
| 1309 | + if (y2 >= VGA_MAX_HEIGHT) | |
| 1310 | + y2 = VGA_MAX_HEIGHT; | |
| 1311 | + for(y = y1; y < y2; y++) { | |
| 1312 | + s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f); | |
| 1313 | + } | |
| 1314 | +} | |
| 1315 | + | |
| 1312 | 1316 | /* |
| 1313 | 1317 | * graphic modes |
| 1314 | - * Missing: | |
| 1315 | - * - double scan | |
| 1316 | - * - double width | |
| 1317 | 1318 | */ |
| 1318 | 1319 | static void vga_draw_graphic(VGAState *s, int full_update) |
| 1319 | 1320 | { |
| ... | ... | @@ -1400,7 +1401,9 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1400 | 1401 | s->last_height = height; |
| 1401 | 1402 | full_update = 1; |
| 1402 | 1403 | } |
| 1403 | - | |
| 1404 | + if (s->cursor_invalidate) | |
| 1405 | + s->cursor_invalidate(s); | |
| 1406 | + | |
| 1404 | 1407 | line_offset = s->line_offset; |
| 1405 | 1408 | #if 0 |
| 1406 | 1409 | printf("w=%d h=%d v=%d line_offset=%d double_scan=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=%02x\n", |
| ... | ... | @@ -1433,6 +1436,8 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1433 | 1436 | /* if wide line, can use another page */ |
| 1434 | 1437 | update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE); |
| 1435 | 1438 | } |
| 1439 | + /* explicit invalidation for the hardware cursor */ | |
| 1440 | + update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; | |
| 1436 | 1441 | if (update) { |
| 1437 | 1442 | if (y_start < 0) |
| 1438 | 1443 | y_start = y; |
| ... | ... | @@ -1441,6 +1446,8 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1441 | 1446 | if (page1 > page_max) |
| 1442 | 1447 | page_max = page1; |
| 1443 | 1448 | vga_draw_line(s, d, s->vram_ptr + addr, width); |
| 1449 | + if (s->cursor_draw_line) | |
| 1450 | + s->cursor_draw_line(s, d, y); | |
| 1444 | 1451 | } else { |
| 1445 | 1452 | if (y_start >= 0) { |
| 1446 | 1453 | /* flush to display */ |
| ... | ... | @@ -1476,6 +1483,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1476 | 1483 | if (page_max != -1) { |
| 1477 | 1484 | cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); |
| 1478 | 1485 | } |
| 1486 | + memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); | |
| 1479 | 1487 | } |
| 1480 | 1488 | |
| 1481 | 1489 | static void vga_draw_blank(VGAState *s, int full_update) | ... | ... |
hw/vga_int.h
| ... | ... | @@ -72,6 +72,7 @@ |
| 72 | 72 | #endif /* !CONFIG_BOCHS_VBE */ |
| 73 | 73 | |
| 74 | 74 | #define CH_ATTR_SIZE (160 * 100) |
| 75 | +#define VGA_MAX_HEIGHT 1024 | |
| 75 | 76 | |
| 76 | 77 | #define VGA_STATE_COMMON \ |
| 77 | 78 | uint8_t *vram_ptr; \ |
| ... | ... | @@ -119,6 +120,10 @@ |
| 119 | 120 | uint32_t cursor_offset; \ |
| 120 | 121 | unsigned int (*rgb_to_pixel)(unsigned int r, \ |
| 121 | 122 | unsigned int g, unsigned b); \ |
| 123 | + /* hardware mouse cursor support */ \ | |
| 124 | + uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; \ | |
| 125 | + void (*cursor_invalidate)(struct VGAState *s); \ | |
| 126 | + void (*cursor_draw_line)(struct VGAState *s, uint8_t *d, int y); \ | |
| 122 | 127 | /* tell for each page if it has been updated since the last time */ \ |
| 123 | 128 | uint32_t last_palette[256]; \ |
| 124 | 129 | uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ |
| ... | ... | @@ -128,10 +133,32 @@ typedef struct VGAState { |
| 128 | 133 | VGA_STATE_COMMON |
| 129 | 134 | } VGAState; |
| 130 | 135 | |
| 136 | +static inline int c6_to_8(int v) | |
| 137 | +{ | |
| 138 | + int b; | |
| 139 | + v &= 0x3f; | |
| 140 | + b = v & 1; | |
| 141 | + return (v << 2) | (b << 1) | b; | |
| 142 | +} | |
| 143 | + | |
| 131 | 144 | void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, |
| 132 | 145 | unsigned long vga_ram_offset, int vga_ram_size); |
| 133 | 146 | uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); |
| 134 | 147 | void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val); |
| 148 | +void vga_invalidate_scanlines(VGAState *s, int y1, int y2); | |
| 149 | + | |
| 150 | +void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1, | |
| 151 | + int poffset, int w, | |
| 152 | + unsigned int color0, unsigned int color1, | |
| 153 | + unsigned int color_xor); | |
| 154 | +void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1, | |
| 155 | + int poffset, int w, | |
| 156 | + unsigned int color0, unsigned int color1, | |
| 157 | + unsigned int color_xor); | |
| 158 | +void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, | |
| 159 | + int poffset, int w, | |
| 160 | + unsigned int color0, unsigned int color1, | |
| 161 | + unsigned int color_xor); | |
| 135 | 162 | |
| 136 | 163 | extern const uint8_t sr_mask[8]; |
| 137 | 164 | extern const uint8_t gr_mask[16]; | ... | ... |
hw/vga_template.h
| ... | ... | @@ -434,6 +434,74 @@ static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, |
| 434 | 434 | #endif |
| 435 | 435 | } |
| 436 | 436 | |
| 437 | +#if DEPTH != 15 | |
| 438 | +void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, | |
| 439 | + const uint8_t *src1, | |
| 440 | + int poffset, int w, | |
| 441 | + unsigned int color0, | |
| 442 | + unsigned int color1, | |
| 443 | + unsigned int color_xor) | |
| 444 | +{ | |
| 445 | + const uint8_t *plane0, *plane1; | |
| 446 | + int x, b0, b1; | |
| 447 | + uint8_t *d; | |
| 448 | + | |
| 449 | + d = d1; | |
| 450 | + plane0 = src1; | |
| 451 | + plane1 = src1 + poffset; | |
| 452 | + for(x = 0; x < w; x++) { | |
| 453 | + b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1; | |
| 454 | + b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1; | |
| 455 | +#if DEPTH == 8 | |
| 456 | + switch(b0 | (b1 << 1)) { | |
| 457 | + case 0: | |
| 458 | + break; | |
| 459 | + case 1: | |
| 460 | + d[0] ^= color_xor; | |
| 461 | + break; | |
| 462 | + case 2: | |
| 463 | + d[0] = color0; | |
| 464 | + break; | |
| 465 | + case 3: | |
| 466 | + d[0] = color1; | |
| 467 | + break; | |
| 468 | + } | |
| 469 | +#elif DEPTH == 16 | |
| 470 | + switch(b0 | (b1 << 1)) { | |
| 471 | + case 0: | |
| 472 | + break; | |
| 473 | + case 1: | |
| 474 | + ((uint16_t *)d)[0] ^= color_xor; | |
| 475 | + break; | |
| 476 | + case 2: | |
| 477 | + ((uint16_t *)d)[0] = color0; | |
| 478 | + break; | |
| 479 | + case 3: | |
| 480 | + ((uint16_t *)d)[0] = color1; | |
| 481 | + break; | |
| 482 | + } | |
| 483 | +#elif DEPTH == 32 | |
| 484 | + switch(b0 | (b1 << 1)) { | |
| 485 | + case 0: | |
| 486 | + break; | |
| 487 | + case 1: | |
| 488 | + ((uint32_t *)d)[0] ^= color_xor; | |
| 489 | + break; | |
| 490 | + case 2: | |
| 491 | + ((uint32_t *)d)[0] = color0; | |
| 492 | + break; | |
| 493 | + case 3: | |
| 494 | + ((uint32_t *)d)[0] = color1; | |
| 495 | + break; | |
| 496 | + } | |
| 497 | +#else | |
| 498 | +#error unsupported depth | |
| 499 | +#endif | |
| 500 | + d += (DEPTH / 8); | |
| 501 | + } | |
| 502 | +} | |
| 503 | +#endif | |
| 504 | + | |
| 437 | 505 | #undef PUT_PIXEL2 |
| 438 | 506 | #undef DEPTH |
| 439 | 507 | #undef BPP | ... | ... |