Commit d34cab9f authored by ths's avatar ths

VMware SVGA II emulation, by Andrzej Zaborowski.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2579 c046a42c-6fe2-441c-8c8c-71466251a162
parent a4080ece
......@@ -403,7 +403,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o
VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o
VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmware_vga.o
CPPFLAGS += -DHAS_AUDIO
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
......
......@@ -3193,6 +3193,9 @@ void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
vga_common_init((VGAState *)s,
ds, vga_ram_base, vga_ram_offset, vga_ram_size);
cirrus_init_common(s, device_id, 1);
graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
s->pci_dev = (PCIDevice *)d;
/* setup memory space */
......
......@@ -664,6 +664,12 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
isa_cirrus_vga_init(ds, phys_ram_base + vga_ram_addr,
vga_ram_addr, vga_ram_size);
}
} else if (vmsvga_enabled) {
if (pci_enabled)
pci_vmsvga_init(pci_bus, ds, phys_ram_base + ram_size,
ram_size, vga_ram_size);
else
fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__);
} else {
if (pci_enabled) {
pci_vga_init(pci_bus, ds, phys_ram_base + vga_ram_addr,
......
......@@ -1788,12 +1788,13 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
s->get_bpp = vga_get_bpp;
s->get_offsets = vga_get_offsets;
s->get_resolution = vga_get_resolution;
graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
vga_screen_dump, s);
s->update = vga_update_display;
s->invalidate = vga_invalidate_display;
s->screen_dump = vga_screen_dump;
}
/* used by both ISA and PCI */
static void vga_init(VGAState *s)
void vga_init(VGAState *s)
{
int vga_io_memory;
......@@ -1856,6 +1857,8 @@ int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
vga_init(s);
graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
......@@ -1881,6 +1884,9 @@ int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
vga_init(s);
graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
s->pci_dev = &d->dev;
pci_conf = d->dev.config;
......
......@@ -134,6 +134,9 @@
uint32_t cursor_offset; \
unsigned int (*rgb_to_pixel)(unsigned int r, \
unsigned int g, unsigned b); \
vga_hw_update_ptr update; \
vga_hw_invalidate_ptr invalidate; \
vga_hw_screen_dump_ptr screen_dump; \
/* hardware mouse cursor support */ \
uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; \
void (*cursor_invalidate)(struct VGAState *s); \
......@@ -157,6 +160,7 @@ static inline int c6_to_8(int v)
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size);
void vga_init(VGAState *s);
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);
......
This diff is collapsed.
......@@ -44,6 +44,9 @@ static int width, height;
static SDL_Cursor *sdl_cursor_normal;
static SDL_Cursor *sdl_cursor_hidden;
static int absolute_enabled = 0;
static int guest_cursor = 0;
static int guest_x, guest_y;
static SDL_Cursor *guest_sprite = 0;
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
{
......@@ -245,13 +248,21 @@ static void sdl_show_cursor(void)
{
if (!kbd_mouse_is_absolute()) {
SDL_ShowCursor(1);
SDL_SetCursor(sdl_cursor_normal);
if (guest_cursor &&
(gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
SDL_SetCursor(guest_sprite);
else
SDL_SetCursor(sdl_cursor_normal);
}
}
static void sdl_grab_start(void)
{
sdl_hide_cursor();
if (guest_cursor) {
SDL_SetCursor(guest_sprite);
SDL_WarpMouse(guest_x, guest_y);
} else
sdl_hide_cursor();
SDL_WM_GrabInput(SDL_GRAB_ON);
/* dummy read to avoid moving the mouse */
SDL_GetRelativeMouseState(NULL, NULL);
......@@ -262,8 +273,8 @@ static void sdl_grab_start(void)
static void sdl_grab_end(void)
{
SDL_WM_GrabInput(SDL_GRAB_OFF);
sdl_show_cursor();
gui_grab = 0;
sdl_show_cursor();
sdl_update_caption();
}
......@@ -294,6 +305,12 @@ static void sdl_send_mouse_event(int dz)
} else if (absolute_enabled) {
sdl_show_cursor();
absolute_enabled = 0;
} else if (guest_cursor) {
SDL_GetMouseState(&dx, &dy);
dx -= guest_x;
dy -= guest_y;
guest_x += dx;
guest_y += dy;
}
kbd_mouse_event(dx, dy, dz, buttons);
......@@ -472,8 +489,77 @@ static void sdl_refresh(DisplayState *ds)
}
}
static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
{
SDL_Rect dst = { x, y, w, h };
SDL_FillRect(screen, &dst, c);
}
static void sdl_mouse_warp(int x, int y, int on)
{
if (on) {
if (!guest_cursor)
sdl_show_cursor();
if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {
SDL_SetCursor(guest_sprite);
SDL_WarpMouse(x, y);
}
} else if (gui_grab)
sdl_hide_cursor();
guest_cursor = on;
guest_x = x, guest_y = y;
}
static void sdl_mouse_define(int width, int height, int bpp,
int hot_x, int hot_y,
uint8_t *image, uint8_t *mask)
{
uint8_t sprite[256], *line;
int x, y, dst, bypl, src = 0;
if (guest_sprite)
SDL_FreeCursor(guest_sprite);
memset(sprite, 0, 256);
bypl = ((width * bpp + 31) >> 5) << 2;
for (y = 0, dst = 0; y < height; y ++, image += bypl) {
line = image;
for (x = 0; x < width; x ++, dst ++) {
switch (bpp) {
case 24:
src = *(line ++); src |= *(line ++); src |= *(line ++);
break;
case 16:
case 15:
src = *(line ++); src |= *(line ++);
break;
case 8:
src = *(line ++);
break;
case 4:
src = 0xf & (line[x >> 1] >> ((x & 1)) << 2);
break;
case 2:
src = 3 & (line[x >> 2] >> ((x & 3)) << 1);
break;
case 1:
src = 1 & (line[x >> 3] >> (x & 7));
break;
}
if (!src)
sprite[dst >> 3] |= (1 << (~dst & 7)) & mask[dst >> 3];
}
}
guest_sprite = SDL_CreateCursor(sprite, mask, width, height, hot_x, hot_y);
if (guest_cursor &&
(gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
SDL_SetCursor(guest_sprite);
}
static void sdl_cleanup(void)
{
if (guest_sprite)
SDL_FreeCursor(guest_sprite);
SDL_Quit();
}
......@@ -510,6 +596,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
ds->dpy_update = sdl_update;
ds->dpy_resize = sdl_resize;
ds->dpy_refresh = sdl_refresh;
ds->dpy_fill = sdl_fill;
ds->mouse_set = sdl_mouse_warp;
ds->cursor_define = sdl_mouse_define;
sdl_resize(ds, 640, 400);
sdl_update_caption();
......
......@@ -154,6 +154,7 @@ QEMUTimer *gui_timer;
int vm_running;
int rtc_utc = 1;
int cirrus_vga_enabled = 1;
int vmsvga_enabled = 0;
#ifdef TARGET_SPARC
int graphic_width = 1024;
int graphic_height = 768;
......@@ -543,6 +544,10 @@ int kbd_mouse_is_absolute(void)
return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
}
void (*kbd_mouse_set)(int x, int y, int on) = NULL;
void (*kbd_cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
uint8_t *image, uint8_t *mask) = NULL;
void do_info_mice(void)
{
QEMUPutMouseEntry *cursor;
......@@ -6509,6 +6514,7 @@ enum {
QEMU_OPTION_k,
QEMU_OPTION_localtime,
QEMU_OPTION_cirrusvga,
QEMU_OPTION_vmsvga,
QEMU_OPTION_g,
QEMU_OPTION_std_vga,
QEMU_OPTION_echr,
......@@ -6616,6 +6622,7 @@ const QEMUOption qemu_options[] = {
/* temporary options */
{ "usb", 0, QEMU_OPTION_usb },
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
{ "vmwarevga", 0, QEMU_OPTION_vmsvga },
{ "no-acpi", 0, QEMU_OPTION_no_acpi },
{ "no-reboot", 0, QEMU_OPTION_no_reboot },
{ "daemonize", 0, QEMU_OPTION_daemonize },
......@@ -7184,9 +7191,15 @@ int main(int argc, char **argv)
break;
case QEMU_OPTION_cirrusvga:
cirrus_vga_enabled = 1;
vmsvga_enabled = 0;
break;
case QEMU_OPTION_vmsvga:
cirrus_vga_enabled = 0;
vmsvga_enabled = 1;
break;
case QEMU_OPTION_std_vga:
cirrus_vga_enabled = 0;
vmsvga_enabled = 0;
break;
case QEMU_OPTION_g:
{
......
......@@ -149,6 +149,7 @@ extern int ram_size;
extern int bios_size;
extern int rtc_utc;
extern int cirrus_vga_enabled;
extern int vmsvga_enabled;
extern int graphic_width;
extern int graphic_height;
extern int graphic_depth;
......@@ -903,7 +904,13 @@ struct DisplayState {
void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
void (*dpy_resize)(struct DisplayState *s, int w, int h);
void (*dpy_refresh)(struct DisplayState *s);
void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h);
void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
int dst_x, int dst_y, int w, int h);
void (*dpy_fill)(struct DisplayState *s, int x, int y,
int w, int h, uint32_t c);
void (*mouse_set)(int x, int y, int on);
void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
uint8_t *image, uint8_t *mask);
};
static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
......@@ -928,6 +935,10 @@ void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size);
/* vmware_vga.c */
void pci_vmsvga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
unsigned long vga_ram_offset, int vga_ram_size);
/* sdl.c */
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment