diff --git a/console.h b/console.h
-index 97214c0..4c51c50 100644
+index 97214c0..8c9b09b 100644
--- a/console.h
+++ b/console.h
-@@ -290,6 +290,9 @@ void vga_hw_update(void);
+@@ -70,6 +70,8 @@ void kbd_put_keysym(int keysym);
+ #define QEMU_BIG_ENDIAN_FLAG 0x01
+ #define QEMU_ALLOCATED_FLAG 0x02
+
++#define INTEL_MAPPED_FLAG 0x04
++
+ struct PixelFormat {
+ uint8_t bits_per_pixel;
+ uint8_t bytes_per_pixel;
+@@ -290,6 +292,11 @@ void vga_hw_update(void);
void vga_hw_invalidate(void);
void vga_hw_screen_dump(const char *filename);
-
+
+void unset_vga_acc(void);
+void set_vga_acc(void);
++extern uint32_t guest_framebuffer;
++extern int intel_output;
+
int is_graphic_console(void);
int is_fixedsize_console(void);
CharDriverState *text_console_init(const char *p);
-@@ -356,4 +359,8 @@ void hid_linux_add_binding(const int *, void (*)(void*), void *);
+@@ -356,4 +363,8 @@ void hid_linux_add_binding(const int *, void (*)(void*), void *);
void hid_linux_reset_keyboard(void);
void hid_linux_probe(int grab);
-
+
+/* intel.c */
+int intel_enter(void);
+int intel_leave(void);
+void intel_display_init(DisplayState *ds);
#endif
diff --git a/hw/vga.c b/hw/vga.c
-index 90bd544..b0f9f9c 100644
+index 90bd544..d515e9d 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -161,6 +161,18 @@ static uint8_t expand4to8[16];
static void vga_bios_init(VGAState *s);
static void vga_screen_dump(void *opaque, const char *filename);
-
+
+static VGAState *xen_vga_state;
+
+void set_vga_acc(void)
static void vga_dumb_update_retrace_info(VGAState *s)
{
(void) s;
-@@ -2473,8 +2485,6 @@ static void vga_bios_init(VGAState *s)
+@@ -1596,15 +1608,12 @@ static void vga_draw_graphic(VGAState *s, int full_update)
+ }
+
+ depth = s->get_bpp(s);
++ guest_framebuffer = s->lfb_addr + (s->start_addr * 4);
+ if (s->line_offset != s->last_line_offset ||
+ disp_width != s->last_width ||
+ height != s->last_height ||
+ s->last_depth != depth) {
+-#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+- if (depth == 16 || depth == 32) {
+-#else
+ if (depth == 32) {
+-#endif
+ if (is_graphic_console()) {
+ qemu_free_displaysurface(s->ds);
+ s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
+@@ -1632,7 +1641,8 @@ static void vga_draw_graphic(VGAState *s, int full_update)
+ s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
+ dpy_setdata(s->ds);
+ }
+-
++ if (intel_output && is_buffer_shared(s->ds->surface))
++ return;
+ s->rgb_to_pixel =
+ rgb_to_pixel_dup_table[get_depth_index(s->ds)];
+
+@@ -2473,8 +2483,6 @@ static void vga_bios_init(VGAState *s)
}
-
-
+
+
-static VGAState *xen_vga_state;
-
/* Allocate video memory in the GPFN space */
{
diff --git a/intel.c b/intel.c
new file mode 100644
-index 0000000..4c5f773
+index 0000000..8a20756
--- /dev/null
+++ b/intel.c
-@@ -0,0 +1,494 @@
+@@ -0,0 +1,405 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+extern int vga_passthrough;
+uint32_t guest_framebuffer;
-+
++int intel_output;
+static int display = 0;
+
+static int mmio_fd = -1;
+static int IntelX = 1280;
+static int IntelY = 1024;
+static DisplayState *lds = NULL;
-+static uint8_t *old_data = NULL;
+static uint32_t intel_fb_base, intel_mmio_base;
+static uint32_t map_s, map_d, map_size;
+static int refresh;
+
-+static void set_data_mappings(void);
-+static void unset_data_mappings(int mapping);
-+static void set_data_pointer(void);
++static void set_data_pointer(DisplaySurface *surf);
+static void intel_resize(DisplayState *ds);
+
+static inline unsigned int intel_get_reg(unsigned int reg)
+ return *dspastride;
+}
+
-+static inline unsigned int intel_get_offset(DisplaySurface *ds, int x, int y)
-+{
-+ return (y * ds->width + x) * 4;
-+}
-+
-+static void intel_update_linear(DisplaySurface *ds, int x, int y, int w, int h)
-+{
-+ int i, bpp = ds->pf.depth / 8;
-+ unsigned char *s, *d;
-+ s = ds->data;
-+ d = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
-+ s += (ds->linesize * y) + bpp * x;
-+ d += (ds->linesize * y) + bpp * x;
-+ for (i = 0; i < h; i++) {
-+ memcpy(d, s, w * bpp);
-+ s += ds->linesize;
-+ d += ds->linesize;
-+ }
-+}
-+
+static void intel_force_linear(int linesize)
+{
+ unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
+ *dspbcntr |= (1 << 31);
+ *pipebconf |= pipeb;
+ }
++ if (linesize) IntelPitch = linesize;
+
+ usleep(20000);
+}
+
-+static void intel_update(DisplayState *ds, int x, int y, int w, int h)
-+{
-+ if (intel_have_focus && !old_data && !map_size)
-+ intel_update_linear(ds->surface, x, y, w, h);
-+}
-+
+static void set_fb_mapping(void)
+{
+ DisplaySurface *surf = lds->surface;
+ unsigned long nr_pfn;
+
+ unset_vga_acc();
-+ fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_reg(REG_DR_DSPASURF)), guest_framebuffer);
-+ nr_pfn = (surf->linesize * surf->height) >> TARGET_PAGE_BITS;
++ INTEL_DEBUG("set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_reg(REG_DR_DSPASURF)), guest_framebuffer);
++ nr_pfn = (ds_get_linesize(lds) * ds_get_height(lds)) >> TARGET_PAGE_BITS;
+
+ rc = xc_domain_memory_mapping(xc_handle,
+ domid,
+ fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
+ return;
+ }
++ memcpy((uint8_t *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)),
++ ds_get_data(lds), ds_get_linesize(lds) * ds_get_height(lds));
+ map_s = ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS);
+ map_d = (guest_framebuffer >> TARGET_PAGE_BITS);
+ map_size = nr_pfn;
+{
+ int rc;
+
-+ fprintf(stderr, "unset_fb_mapping: %x %x\n", map_d, map_s);
++ INTEL_DEBUG("unset_fb_mapping: %x %x\n", map_d, map_s);
+
+ rc = xc_domain_memory_mapping(xc_handle,
+ domid,
+ }
+
+ set_vga_acc();
++ memcpy(ds_get_data(lds),
++ (uint8_t *) (intel_mem + intel_get_reg(REG_DR_DSPASURF)),
++ ds_get_linesize(lds) * ds_get_height(lds));
+ map_s = 0;
+ map_d = 0;
+ map_size = 0;
+}
+
-+static void intel_setdata(DisplayState *ds)
++
++static void intel_update(DisplayState *ds, int x, int y, int w, int h)
+{
-+ if (map_size)
-+ unset_fb_mapping();
-+ set_fb_mapping();
++ /* do nothing */
+}
+
-+static void intel_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
++static void intel_resize(DisplayState *ds)
+{
-+ DisplaySurface *surf = ds->surface;
-+
-+ if (!intel_have_focus) {
-+ surf->width = w;
-+ surf->height = h;
-+ intel_resize(ds);
-+ return;
++ INTEL_DEBUG("intel_resize: shared=%d\n", is_buffer_shared(ds->surface));
++ if (intel_have_focus) {
++ if (!is_buffer_shared(ds->surface) && !is_linear())
++ intel_force_linear(0);
++ else if (!is_linear() || IntelPitch != ds_get_linesize(lds))
++ intel_force_linear(ds_get_linesize(lds));
+ }
-+ if (depth == 32 && w == IntelX && h == IntelY)
-+ surf->flags = QEMU_ALLOCATED_FLAG;
-+ else
-+ surf->flags &= ~QEMU_ALLOCATED_FLAG;
-+ if (surf->flags & QEMU_ALLOCATED_FLAG) {
-+ surf->width = w;
-+ surf->height = h;
-+ surf->pf.depth = 32;
-+ surf->linesize = linesize;
-+ /* adjust linesize */
-+ intel_force_linear(linesize);
-+ set_data_mappings();
-+ if (refresh) {
-+ memcpy(surf->data, pixels, surf->linesize * surf->height);
-+ refresh = 0;
++ if (!is_buffer_shared(ds->surface))
++ return;
++ if (intel_have_focus) {
++ if (!map_size) {
++ set_fb_mapping();
+ }
-+ surf->data = pixels;
-+ intel_setdata(ds);
+ } else {
-+ surf->width = w;
-+ surf->height = h;
-+ intel_resize(ds);
++ if (map_size) {
++ unset_fb_mapping();
++ }
+ }
+}
+
-+static void intel_resize(DisplayState *ds)
++static void intel_setdata(DisplayState *ds)
+{
-+ DisplaySurface *surf = ds->surface;
-+ int old_linesize = surf->linesize;
-+
-+ if (surf->pf.depth == 32 && surf->width == IntelX && surf->height == IntelY)
-+ surf->flags = QEMU_ALLOCATED_FLAG;
-+ else
-+ surf->flags &= ~QEMU_ALLOCATED_FLAG;
-+
-+ if (is_buffer_shared(surf))
-+ {
-+ INTEL_DEBUG("intel_resize_shared: enable shared buffer, linesize %d\n",
-+ surf->linesize);
-+ intel_force_linear(surf->linesize);
-+ set_data_mappings();
-+ if (refresh)
-+ {
-+ // Pixels doesn't exist anymore ??
-+ //memcpy(surf->data, pixels, surf->linesize * surf->height);
-+ refresh = 0;
-+ }
-+ intel_setdata(ds);
-+ return;
-+ }
-+
-+ INTEL_DEBUG("intel_resize: no shared buffer, linesize=%d\n", surf->linesize);
-+ surf->linesize = intel_get_pitch();
-+ if (map_size) {
-+ unset_fb_mapping();
-+ unset_data_mappings(1);
-+ }
-+ if (intel_have_focus && !is_linear()) {
-+ intel_force_linear(0);
-+ }
-+ surf->flags &= ~QEMU_ALLOCATED_FLAG;
-+ if (intel_have_focus && !old_data &&
-+ surf->width * surf->height <= IntelX * IntelY)
-+ set_data_mappings();
-+ else if (intel_have_focus && old_data &&
-+ surf->width * surf->height > IntelX * IntelY)
-+ unset_data_mappings(0);
-+ if (!old_data) {
-+ qemu_free(surf->data);
-+ surf->data = qemu_mallocz(surf->height * surf->linesize);
-+ } else {
-+ INTEL_DEBUG("intel_resize: set_data_pointer\n");
-+ set_data_pointer();
-+ }
-+ if (intel_have_focus)
-+ memset((unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)), 0x0, IntelX * IntelY);
-+ if (refresh) {
-+ if (old_data) {
-+ unsigned char *s, *d;
-+ int i;
-+ s = old_data;
-+ d = surf->data;
-+ for (i = 0; i < surf->height; i++) {
-+ memcpy(d, s, surf->width * 4);
-+ s += old_linesize;
-+ d += surf->linesize;
-+ }
-+ }
-+ refresh = 0;
-+ }
++ if (!map_size)
++ return;
++ unset_fb_mapping();
++ set_fb_mapping();
+}
+
+static void intel_refresh(DisplayState *ds)
+ INTEL_DEBUG("Map intel mmio 0x%x\n", intel_mmio_base);
+ intel_mmio = mmap(NULL, 4 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED,
+ mmio_fd, intel_mmio_base);
-+ if (intel_mem == MAP_FAILED)
++ if (intel_mmio == MAP_FAILED)
+ {
+ perror("mmap");
+ exit(1);
+ }
+}
+
-+static void set_data_pointer(void)
++static void set_data_pointer(DisplaySurface *surf)
+{
-+ DisplaySurface *surf = lds->surface;
-+
+ surf->data = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
++ memset(surf->data, 0x00, surf->linesize * IntelY);
+ surf->data = surf->data +
+ surf->linesize * ((IntelY - surf->height) / 2) +
+ 4 * ((IntelX - surf->width) / 2);
+}
+
-+static void set_data_mappings(void)
-+{
-+ INTEL_DEBUG("set_data_mappings\n");
-+ if (!old_data)
-+ old_data = lds->surface->data;
-+ set_data_pointer();
-+}
-+
-+static void unset_data_mappings(int mapping)
-+{
-+ DisplaySurface *surf = lds->surface;
-+ if (!old_data)
-+ return;
-+ if (mapping) {
-+ uint8_t * buffer_pointer = surf->data;
-+ surf->data = old_data;
-+ old_data = NULL;
-+ surf->data = realloc(surf->data, surf->linesize * surf->height);
-+ memcpy(surf->data,
-+ (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)),
-+ surf->linesize * surf->height);
-+ memcpy(buffer_pointer,
-+ surf->data,
-+ surf->linesize * surf->height);
-+ } else {
-+ uint8_t * buffer_pointer = surf->data;
-+ surf->data = old_data;
-+ old_data = NULL;
-+ surf->data = realloc(surf->data, surf->linesize * surf->height);
-+ memcpy(surf->data,
-+ buffer_pointer,
-+ surf->linesize * surf->height);
-+ }
-+ INTEL_DEBUG("unset_data_mappings %d: success\n", mapping);
-+}
-+
+static int intel_getfocus(void)
+{
+ return intel_have_focus;
+
+ INTEL_DEBUG("intel_focus %d\n", focus);
+ intel_have_focus = focus;
-+ if (focus) {
-+ if (!is_linear()) {
-+ IntelPitch = intel_get_reg(REG_DR_DSPASTRIDE);
-+ IntelX = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
-+ IntelY = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
-+ INTEL_DEBUG("Resolution is %dx%d\n", IntelX, IntelY);
-+ }
-+ refresh = 1;
-+ lds->listeners->dpy_resize = intel_resize;
-+ lds->listeners->dpy_setdata = intel_setdata;
-+ vga_hw_invalidate();
-+ } else {
-+ if (map_size) {
-+ unset_fb_mapping();
-+ unset_data_mappings(1);
-+ } else if (old_data) {
-+ unset_data_mappings(0);
-+ }
-+ lds->listeners->dpy_resize = NULL;
-+ lds->listeners->dpy_setdata = NULL;
-+ lds->surface->flags &= ~QEMU_ALLOCATED_FLAG;
++ if (intel_have_focus) {
++ IntelPitch = intel_get_reg(REG_DR_DSPASTRIDE);
++ IntelX = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
++ IntelY = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
+ }
++ vga_hw_invalidate();
++ vga_hw_update();
+}
+
+int intel_enter(void)
+ return 1;
+}
+
-+void intel_display_init(DisplayState *ds)
++static DisplaySurface* intel_create_displaysurface(int width, int height)
++{
++ DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
++ if (surface == NULL) {
++ fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
++ exit(1);
++ }
++
++ surface->width = width;
++ surface->height = height;
++
++ INTEL_DEBUG("intel_create_displaysurface: focus=%d %d %d\n", intel_have_focus, width, height);
++ if (intel_have_focus) {
++ surface->pf = qemu_default_pixelformat(32);
++ surface->flags = QEMU_ALLOCATED_FLAG | INTEL_MAPPED_FLAG;
++ surface->linesize = IntelPitch;
++ set_data_pointer(surface);
++ } else {
++ surface->data = qemu_mallocz(width * height * 4);
++ surface->linesize = width * 4;
++ surface->pf = qemu_default_pixelformat(32);
++ surface->flags = QEMU_ALLOCATED_FLAG;
++ }
++
++ return surface;
++}
++
++static void intel_free_displaysurface(DisplaySurface *surface)
+{
-+ DisplaySurface *surf = ds->surface;
++ if (surface == NULL)
++ return;
++ if ((!(surface->flags & INTEL_MAPPED_FLAG)) && (surface->flags & QEMU_ALLOCATED_FLAG))
++ qemu_free(surface->data);
++ qemu_free(surface);
++}
+
-+ INTEL_DEBUG("\n");
++static DisplaySurface* intel_resize_displaysurface(DisplaySurface *surface, int width, int height)
++{
++ intel_free_displaysurface(surface);
++ return intel_create_displaysurface(width, height);
++}
++
++void intel_display_init(DisplayState *ds)
++{
++ DisplayChangeListener *dcl;
++ DisplayAllocator *da;
+
+ intel_init_mapping();
+
+ INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_reg(REG_DR_DSPASURF));
+
-+ surf->flags = 0;
-+ surf->width = 640;
-+ surf->height = 480;
-+ surf->pf.depth = 32;
-+ intel_resize(ds);
-+ lds = ds;
++ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
++ if (!dcl)
++ exit(1);
++ dcl->dpy_update = intel_update;
++ dcl->dpy_resize = intel_resize;
++ dcl->dpy_setdata = intel_setdata;
++ dcl->dpy_refresh = intel_refresh;
++ register_displaychangelistener(ds, dcl);
++
++ da = qemu_mallocz(sizeof(DisplayAllocator));
++ if (!da)
++ exit(1);
++ da->create_displaysurface = intel_create_displaysurface;
++ da->resize_displaysurface = intel_resize_displaysurface;
++ da->free_displaysurface = intel_free_displaysurface;
++ if (register_displayallocator(ds, da) != da) {
++ fprintf(stderr, "intel_display_init: could not register DisplayAllocator\n");
++ exit(1);
++ } else {
++ DisplaySurface *surf;
++ surf = intel_create_displaysurface(ds_get_width(ds), ds_get_height(ds));
++ defaultallocator_free_displaysurface(ds->surface);
++ ds->surface = surf;
++ dpy_resize(ds);
++ }
+
-+ ds->listeners->dpy_update = intel_update;
-+ ds->listeners->dpy_resize = intel_resize;
-+ ds->listeners->dpy_refresh = intel_refresh;
++ intel_output = 1;
++ lds = ds;
+}
diff --git a/vl.c b/vl.c
-index 0ffe1ec..d6379a9 100644
+index 18c2a8a..bb83e19 100644
--- a/vl.c
+++ b/vl.c
@@ -235,6 +235,7 @@ int win2k_install_hack = 0;
QEMU_OPTION_vga_passthrough,
QEMU_OPTION_dom0_input,
+ QEMU_OPTION_intel,
-
+
/* Debug/Expert options: */
QEMU_OPTION_serial,
@@ -4468,6 +4470,7 @@ static const QEMUOption qemu_options[] = {
{ "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
{ "vga-passthrough", 0, QEMU_OPTION_vga_passthrough },
{ "dom0-input", 1, QEMU_OPTION_dom0_input },
-+ { "intel", 0, QEMU_OPTION_dom0_input },
++ { "intel", 0, QEMU_OPTION_intel },
#if defined(CONFIG_XEN) && !defined(CONFIG_DM)
{ "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
{ "xen-create", 0, QEMU_OPTION_xen_create },
-@@ -5307,6 +5310,9 @@ int main(int argc, char **argv, char **envp)
+@@ -5306,6 +5309,9 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_dom0_input:
dom0_input = optarg;
break;
case QEMU_OPTION_direct_pci:
direct_pci = optarg;
break;
+@@ -5908,26 +5914,26 @@ int main(int argc, char **argv, char **envp)
+ curses_display_init(ds, full_screen);
+ } else
+ #endif
+- {
+- if (vnc_display != NULL || vncunused != 0) {
+- int vnc_display_port;
+- char password[20];
+- vnc_display_init(ds);
+- xenstore_read_vncpasswd(domid, password, sizeof(password));
+- vnc_display_password(ds, password);
+- vnc_display_port = vnc_display_open(ds, vnc_display, vncunused);
+- if (vnc_display_port < 0)
+- exit(1);
+- xenstore_write_vncport(vnc_display_port);
+- }
++ if (intel)
++ intel_display_init(ds);
++ if (vnc_display != NULL || vncunused != 0) {
++ int vnc_display_port;
++ char password[20];
++ vnc_display_init(ds);
++ xenstore_read_vncpasswd(domid, password, sizeof(password));
++ vnc_display_password(ds, password);
++ vnc_display_port = vnc_display_open(ds, vnc_display, vncunused);
++ if (vnc_display_port < 0)
++ exit(1);
++ xenstore_write_vncport(vnc_display_port);
++ }
+ #if defined(CONFIG_SDL)
+- if (sdl || !vnc_display)
+- sdl_display_init(ds, full_screen, no_frame, opengl_enabled);
++ if (sdl || !vnc_display)
++ sdl_display_init(ds, full_screen, no_frame, opengl_enabled);
+ #elif defined(CONFIG_COCOA)
+- if (sdl || !vnc_display)
+- cocoa_display_init(ds, full_screen);
++ if (sdl || !vnc_display)
++ cocoa_display_init(ds, full_screen);
+ #endif
+- }
+ }
+ dpy_resize(ds);
+
diff --git a/xen-hooks.mak b/xen-hooks.mak
index f243df1..55dd477 100644
--- a/xen-hooks.mak
OBJS += dom0_driver.o
OBJS += hid-linux.o
+OBJS += intel.o
-
+
ifdef CONFIG_STUBDOM
CPPFLAGS += $(TARGET_CPPFLAGS) -DNEED_CPU_H \