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