Commit a8aa669ba406a0d6530f48e0c87a358ba614aa95

Authored by bellard
1 parent a5082316

generic hardware cursor support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@903 c046a42c-6fe2-441c-8c8c-71466251a162
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