mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
generic hardware cursor support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@903 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
a5082316e9
commit
a8aa669ba4
3 changed files with 115 additions and 12 deletions
32
hw/vga.c
32
hw/vga.c
|
@ -852,14 +852,6 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign
|
|||
#define DEPTH 32
|
||||
#include "vga_template.h"
|
||||
|
||||
static inline int c6_to_8(int v)
|
||||
{
|
||||
int b;
|
||||
v &= 0x3f;
|
||||
b = v & 1;
|
||||
return (v << 2) | (b << 1) | b;
|
||||
}
|
||||
|
||||
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
|
||||
{
|
||||
unsigned int col;
|
||||
|
@ -1309,11 +1301,20 @@ static int vga_get_bpp(VGAState *s)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void vga_invalidate_scanlines(VGAState *s, int y1, int y2)
|
||||
{
|
||||
int y;
|
||||
if (y1 >= VGA_MAX_HEIGHT)
|
||||
return;
|
||||
if (y2 >= VGA_MAX_HEIGHT)
|
||||
y2 = VGA_MAX_HEIGHT;
|
||||
for(y = y1; y < y2; y++) {
|
||||
s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* graphic modes
|
||||
* Missing:
|
||||
* - double scan
|
||||
* - double width
|
||||
*/
|
||||
static void vga_draw_graphic(VGAState *s, int full_update)
|
||||
{
|
||||
|
@ -1400,7 +1401,9 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|||
s->last_height = height;
|
||||
full_update = 1;
|
||||
}
|
||||
|
||||
if (s->cursor_invalidate)
|
||||
s->cursor_invalidate(s);
|
||||
|
||||
line_offset = s->line_offset;
|
||||
#if 0
|
||||
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)
|
|||
/* if wide line, can use another page */
|
||||
update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE);
|
||||
}
|
||||
/* explicit invalidation for the hardware cursor */
|
||||
update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
|
||||
if (update) {
|
||||
if (y_start < 0)
|
||||
y_start = y;
|
||||
|
@ -1441,6 +1446,8 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|||
if (page1 > page_max)
|
||||
page_max = page1;
|
||||
vga_draw_line(s, d, s->vram_ptr + addr, width);
|
||||
if (s->cursor_draw_line)
|
||||
s->cursor_draw_line(s, d, y);
|
||||
} else {
|
||||
if (y_start >= 0) {
|
||||
/* flush to display */
|
||||
|
@ -1476,6 +1483,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
|
|||
if (page_max != -1) {
|
||||
cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE);
|
||||
}
|
||||
memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
|
||||
}
|
||||
|
||||
static void vga_draw_blank(VGAState *s, int full_update)
|
||||
|
|
27
hw/vga_int.h
27
hw/vga_int.h
|
@ -72,6 +72,7 @@
|
|||
#endif /* !CONFIG_BOCHS_VBE */
|
||||
|
||||
#define CH_ATTR_SIZE (160 * 100)
|
||||
#define VGA_MAX_HEIGHT 1024
|
||||
|
||||
#define VGA_STATE_COMMON \
|
||||
uint8_t *vram_ptr; \
|
||||
|
@ -119,6 +120,10 @@
|
|||
uint32_t cursor_offset; \
|
||||
unsigned int (*rgb_to_pixel)(unsigned int r, \
|
||||
unsigned int g, unsigned b); \
|
||||
/* hardware mouse cursor support */ \
|
||||
uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; \
|
||||
void (*cursor_invalidate)(struct VGAState *s); \
|
||||
void (*cursor_draw_line)(struct VGAState *s, uint8_t *d, int y); \
|
||||
/* tell for each page if it has been updated since the last time */ \
|
||||
uint32_t last_palette[256]; \
|
||||
uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
|
||||
|
@ -128,10 +133,32 @@ typedef struct VGAState {
|
|||
VGA_STATE_COMMON
|
||||
} VGAState;
|
||||
|
||||
static inline int c6_to_8(int v)
|
||||
{
|
||||
int b;
|
||||
v &= 0x3f;
|
||||
b = v & 1;
|
||||
return (v << 2) | (b << 1) | b;
|
||||
}
|
||||
|
||||
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
|
||||
unsigned long vga_ram_offset, int vga_ram_size);
|
||||
uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
|
||||
void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
|
||||
void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
|
||||
|
||||
void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1,
|
||||
int poffset, int w,
|
||||
unsigned int color0, unsigned int color1,
|
||||
unsigned int color_xor);
|
||||
void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1,
|
||||
int poffset, int w,
|
||||
unsigned int color0, unsigned int color1,
|
||||
unsigned int color_xor);
|
||||
void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
|
||||
int poffset, int w,
|
||||
unsigned int color0, unsigned int color1,
|
||||
unsigned int color_xor);
|
||||
|
||||
extern const uint8_t sr_mask[8];
|
||||
extern const uint8_t gr_mask[16];
|
||||
|
|
|
@ -434,6 +434,74 @@ static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if DEPTH != 15
|
||||
void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
|
||||
const uint8_t *src1,
|
||||
int poffset, int w,
|
||||
unsigned int color0,
|
||||
unsigned int color1,
|
||||
unsigned int color_xor)
|
||||
{
|
||||
const uint8_t *plane0, *plane1;
|
||||
int x, b0, b1;
|
||||
uint8_t *d;
|
||||
|
||||
d = d1;
|
||||
plane0 = src1;
|
||||
plane1 = src1 + poffset;
|
||||
for(x = 0; x < w; x++) {
|
||||
b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
|
||||
b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
|
||||
#if DEPTH == 8
|
||||
switch(b0 | (b1 << 1)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
d[0] ^= color_xor;
|
||||
break;
|
||||
case 2:
|
||||
d[0] = color0;
|
||||
break;
|
||||
case 3:
|
||||
d[0] = color1;
|
||||
break;
|
||||
}
|
||||
#elif DEPTH == 16
|
||||
switch(b0 | (b1 << 1)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
((uint16_t *)d)[0] ^= color_xor;
|
||||
break;
|
||||
case 2:
|
||||
((uint16_t *)d)[0] = color0;
|
||||
break;
|
||||
case 3:
|
||||
((uint16_t *)d)[0] = color1;
|
||||
break;
|
||||
}
|
||||
#elif DEPTH == 32
|
||||
switch(b0 | (b1 << 1)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
((uint32_t *)d)[0] ^= color_xor;
|
||||
break;
|
||||
case 2:
|
||||
((uint32_t *)d)[0] = color0;
|
||||
break;
|
||||
case 3:
|
||||
((uint32_t *)d)[0] = color1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
#error unsupported depth
|
||||
#endif
|
||||
d += (DEPTH / 8);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef PUT_PIXEL2
|
||||
#undef DEPTH
|
||||
#undef BPP
|
||||
|
|
Loading…
Reference in a new issue