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,14 +852,6 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign | ||
| 852 | #define DEPTH 32 | 852 | #define DEPTH 32 |
| 853 | #include "vga_template.h" | 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 | static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b) | 855 | static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b) |
| 864 | { | 856 | { |
| 865 | unsigned int col; | 857 | unsigned int col; |
| @@ -1309,11 +1301,20 @@ static int vga_get_bpp(VGAState *s) | @@ -1309,11 +1301,20 @@ static int vga_get_bpp(VGAState *s) | ||
| 1309 | return ret; | 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 | * graphic modes | 1317 | * graphic modes |
| 1314 | - * Missing: | ||
| 1315 | - * - double scan | ||
| 1316 | - * - double width | ||
| 1317 | */ | 1318 | */ |
| 1318 | static void vga_draw_graphic(VGAState *s, int full_update) | 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,7 +1401,9 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
| 1400 | s->last_height = height; | 1401 | s->last_height = height; |
| 1401 | full_update = 1; | 1402 | full_update = 1; |
| 1402 | } | 1403 | } |
| 1403 | - | 1404 | + if (s->cursor_invalidate) |
| 1405 | + s->cursor_invalidate(s); | ||
| 1406 | + | ||
| 1404 | line_offset = s->line_offset; | 1407 | line_offset = s->line_offset; |
| 1405 | #if 0 | 1408 | #if 0 |
| 1406 | printf("w=%d h=%d v=%d line_offset=%d double_scan=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=%02x\n", | 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,6 +1436,8 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
| 1433 | /* if wide line, can use another page */ | 1436 | /* if wide line, can use another page */ |
| 1434 | update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE); | 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 | if (update) { | 1441 | if (update) { |
| 1437 | if (y_start < 0) | 1442 | if (y_start < 0) |
| 1438 | y_start = y; | 1443 | y_start = y; |
| @@ -1441,6 +1446,8 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1441,6 +1446,8 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
| 1441 | if (page1 > page_max) | 1446 | if (page1 > page_max) |
| 1442 | page_max = page1; | 1447 | page_max = page1; |
| 1443 | vga_draw_line(s, d, s->vram_ptr + addr, width); | 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 | } else { | 1451 | } else { |
| 1445 | if (y_start >= 0) { | 1452 | if (y_start >= 0) { |
| 1446 | /* flush to display */ | 1453 | /* flush to display */ |
| @@ -1476,6 +1483,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1476,6 +1483,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
| 1476 | if (page_max != -1) { | 1483 | if (page_max != -1) { |
| 1477 | cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); | 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 | static void vga_draw_blank(VGAState *s, int full_update) | 1489 | static void vga_draw_blank(VGAState *s, int full_update) |
hw/vga_int.h
| @@ -72,6 +72,7 @@ | @@ -72,6 +72,7 @@ | ||
| 72 | #endif /* !CONFIG_BOCHS_VBE */ | 72 | #endif /* !CONFIG_BOCHS_VBE */ |
| 73 | 73 | ||
| 74 | #define CH_ATTR_SIZE (160 * 100) | 74 | #define CH_ATTR_SIZE (160 * 100) |
| 75 | +#define VGA_MAX_HEIGHT 1024 | ||
| 75 | 76 | ||
| 76 | #define VGA_STATE_COMMON \ | 77 | #define VGA_STATE_COMMON \ |
| 77 | uint8_t *vram_ptr; \ | 78 | uint8_t *vram_ptr; \ |
| @@ -119,6 +120,10 @@ | @@ -119,6 +120,10 @@ | ||
| 119 | uint32_t cursor_offset; \ | 120 | uint32_t cursor_offset; \ |
| 120 | unsigned int (*rgb_to_pixel)(unsigned int r, \ | 121 | unsigned int (*rgb_to_pixel)(unsigned int r, \ |
| 121 | unsigned int g, unsigned b); \ | 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 | /* tell for each page if it has been updated since the last time */ \ | 127 | /* tell for each page if it has been updated since the last time */ \ |
| 123 | uint32_t last_palette[256]; \ | 128 | uint32_t last_palette[256]; \ |
| 124 | uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ | 129 | uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */ |
| @@ -128,10 +133,32 @@ typedef struct VGAState { | @@ -128,10 +133,32 @@ typedef struct VGAState { | ||
| 128 | VGA_STATE_COMMON | 133 | VGA_STATE_COMMON |
| 129 | } VGAState; | 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 | void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, | 144 | void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, |
| 132 | unsigned long vga_ram_offset, int vga_ram_size); | 145 | unsigned long vga_ram_offset, int vga_ram_size); |
| 133 | uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); | 146 | uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); |
| 134 | void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val); | 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 | extern const uint8_t sr_mask[8]; | 163 | extern const uint8_t sr_mask[8]; |
| 137 | extern const uint8_t gr_mask[16]; | 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,6 +434,74 @@ static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, | ||
| 434 | #endif | 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 | #undef PUT_PIXEL2 | 505 | #undef PUT_PIXEL2 |
| 438 | #undef DEPTH | 506 | #undef DEPTH |
| 439 | #undef BPP | 507 | #undef BPP |