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 |