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 | ... | ... |