]> xenbits.xensource.com Git - qemu-xen-3.3-testing.git/commitdiff
Update to xen-unstable 17737 plus ds->resize_shared vs. ds_resize
authorIan Jackson <iwj@mariner.uk.xensource.com>
Wed, 4 Jun 2008 17:14:41 +0000 (18:14 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 4 Jun 2008 17:14:41 +0000 (18:14 +0100)
This one commit contains two substantial sets of changes:

 * All changes from xen-unstable from 17647 to 17737:c93a913c221f

 * Shared display buffer API revamp
    Patch from Stefano Stabellini <stefano.stabellini@eu.citrix.com>, to
    do shared display buffer stuff with a different (backward-compatible)
    API which avoids having to change all of the other display hardware
    models.  Stefano tells me this patch is likely to break stubdom in
    its current state.

The commit is the result of applying Stefano's patch to xen-unstable
hg 17737, then running  hg diff -r17647 tools/ioemu, applying the
output to the git tree with patch, and fixing up the conflicts (which
were easy).

To make future merges easier, I have included Stefano's patch rebased
to 17737 (the result of hg diff -r17737 from the above hg tree) here,
so that the base point for a future merge to a new xen-unstable tip is
easy to recreate.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
12 files changed:
console.h
hw/cirrus_vga.c
hw/pc.c
hw/pc.h
hw/piix4acpi.c
hw/serial.c
hw/vga.c
hw/xenfb.c
i386-dm/helper2.c
sdl.c
vga-patch-from-xen-unstable-17737:c93a913c221f [new file with mode: 0644]
vnc.c

index 7bb1945be1b04deb5f1e9817c6ce236fc4c7bd63..6cb34b90a9eed8e0caa82394452c0bff7413ce4c 100644 (file)
--- a/console.h
+++ b/console.h
@@ -81,7 +81,7 @@ 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_colourdepth)(struct DisplayState *s, int depth);
+    void (*dpy_resize_shared)(struct DisplayState *s, int w, int h, int linesize);
     void (*dpy_setdata)(DisplayState *s, void *pixels);
     void (*dpy_refresh)(struct DisplayState *s);
     void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
@@ -99,6 +99,10 @@ static inline void dpy_resize(DisplayState *s, int w, int h)
 {
     s->dpy_resize(s, w, h);
 }
+static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels)
+{
+    s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
+}
 
 typedef unsigned long console_ch_t;
 
index 209c200689e4248c8d910b77f28f8c81a8bfc7d9..14618763804df39fb7d6f6a9bb5eafb20df4e38d 100644 (file)
@@ -301,8 +301,6 @@ typedef struct PCICirrusVGAState {
 
 static uint8_t rop_to_index[256];
 
-void *shared_vram;
-
 /***************************************
  *
  *  prototypes.
diff --git a/hw/pc.c b/hw/pc.c
index cba5ae35fde6a8186c5de43af7caf1d303b73a87..fa3ca1ac21ff9c82f674611b3da761e4539761d4 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1140,6 +1140,14 @@ static void pc_init_isa(ram_addr_t ram_size, int vga_ram_size,
              direct_pci);
 }
 
+/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
+   BIOS will read it and start S3 resume at POST Entry*/
+void cmos_set_s3_resume(void)
+{
+    if (rtc_state)
+        rtc_set_memory(rtc_state, 0xF, 0xFE);
+}
+
 QEMUMachine pc_machine = {
     "pc",
     "Standard PC",
diff --git a/hw/pc.h b/hw/pc.h
index a472a2b304b953a2a0cb0a4e97177694f63cf279..a78e0393bdb739ee46e925868e1a4faa5bcecdee 100644 (file)
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -89,6 +89,7 @@ extern int fd_bootchk;
 
 void ioport_set_a20(int enable);
 int ioport_get_a20(void);
+void cmos_set_s3_resume(void);
 
 /* acpi.c */
 extern int acpi_enabled;
index a8b97fdf11f27f679d813aed6975ec9e031ee899..7a77d37dfc5417b61a59fe7567f0d35016fa85f2 100644 (file)
@@ -29,6 +29,7 @@
 #include "sysemu.h"
 
 #include <xen/hvm/ioreq.h>
+#include <xen/hvm/params.h>
 
 /* PM1a_CNT bits, as defined in the ACPI specification. */
 #define SCI_EN            (1 <<  0)
@@ -39,6 +40,7 @@
 /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */
 /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */
 #define SLP_TYP_S4        (6 << 10)
+#define SLP_TYP_S3        (5 << 10)
 #define SLP_TYP_S5        (7 << 10)
 
 #define ACPI_DBG_IO_ADDR  0xb044
@@ -80,6 +82,7 @@ typedef struct PHPSlots {
 } PHPSlots;
 
 PHPSlots php_slots;
+static int s3_shutdown_flag;
 static qemu_irq sci_irq;
 
 static void piix4acpi_save(QEMUFile *f, void *opaque)
@@ -121,6 +124,13 @@ static void acpi_shutdown(uint32_t val)
         return;
 
     switch (val & SLP_TYP_Sx) {
+    case SLP_TYP_S3:
+        s3_shutdown_flag = 1;
+        qemu_system_reset();
+        s3_shutdown_flag = 0;
+        cmos_set_s3_resume();
+        xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3);
+        break;
     case SLP_TYP_S4:
     case SLP_TYP_S5:
         qemu_system_shutdown_request();
index f46b79aceb6452d5c5db31af0c1804badeb5a220..0faeedba5539c432239137d936d6a13c681825cf 100644 (file)
@@ -723,12 +723,13 @@ static void serial_save(QEMUFile *f, void *opaque)
     qemu_put_8s(f,&s->lsr);
     qemu_put_8s(f,&s->msr);
     qemu_put_8s(f,&s->scr);
-    qemu_get_8s(f,&s->fcr);
+    qemu_put_8s(f,&s->fcr);
 }
 
 static int serial_load(QEMUFile *f, void *opaque, int version_id)
 {
     SerialState *s = opaque;
+    uint8_t fcr = 0;
 
     if(version_id > 2)
         return -EINVAL;
@@ -747,6 +748,11 @@ static int serial_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_8s(f,&s->scr);
     qemu_get_8s(f,&s->fcr);
 
+    if (version_id >= 2)
+        qemu_get_8s(f,&fcr);
+
+    /* Initialize fcr via setter to perform essential side-effects */
+    serial_ioport_write(s, 0x02, fcr);
     return 0;
 }
 
index 73c301b8fd291acac1c4969bc5f353d8300abe1d..e791ba2be1e57174d069a0d38fc79ae305a2d99d 100644 (file)
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1068,6 +1068,8 @@ typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsig
 
 static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];
 
+static int old_depth = 0;
+
 /*
  * Text mode update
  * Missing:
@@ -1092,14 +1094,51 @@ static void vga_draw_text(VGAState *s, int full_update)
     /* Disable dirty bit tracking */
     xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
 
-    if (s->ds->dpy_colourdepth != NULL && s->ds->depth != 0)
-        s->ds->dpy_colourdepth(s->ds, 0);
-    s->rgb_to_pixel =
+    /* total width & height */
+    cheight = (s->cr[9] & 0x1f) + 1;
+    cw = 8;
+    if (!(s->sr[1] & 0x01))
+        cw = 9;
+    if (s->sr[1] & 0x08)
+        cw = 16; /* NOTE: no 18 pixel wide */
+    width = (s->cr[0x01] + 1);
+    if (s->cr[0x06] == 100) {
+        /* ugly hack for CGA 160x100x16 - explain me the logic */
+        height = 100;
+    } else {
+        height = s->cr[0x12] |
+            ((s->cr[0x07] & 0x02) << 7) |
+            ((s->cr[0x07] & 0x40) << 3);
+        height = (height + 1) / cheight;
+    }
+    if ((height * width) > CH_ATTR_SIZE) {
+        /* better than nothing: exit if transient size is too big */
+        return;
+    }
+
+    s->last_scr_width = width * cw;
+    s->last_scr_height = height * cheight;
+    if (s->ds->dpy_resize_shared && old_depth) {
+        dpy_resize_shared(s->ds, s->last_scr_width, s->last_scr_height, 0, s->last_scr_width * (s->ds->depth / 8), NULL);
+        old_depth = 0;
+        full_update = 1;
+    } else if (width != s->last_width || height != s->last_height ||
+        cw != s->last_cw || cheight != s->last_ch) {
+        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
+        full_update = 1;
+    }
+    s->last_width = width;
+    s->last_height = height;
+    s->last_ch = cheight;
+    s->last_cw = cw;
+
+    s->rgb_to_pixel = 
         rgb_to_pixel_dup_table[get_depth_index(s->ds)];
 
     full_update |= update_palette16(s);
     palette = s->last_palette;
-
+    
+    x_incr = cw * ((s->ds->depth + 7) >> 3);
     /* compute font data address (in plane 2) */
     v = s->sr[3];
     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
@@ -1126,40 +1165,6 @@ static void vga_draw_text(VGAState *s, int full_update)
     line_offset = s->line_offset;
     s1 = s->vram_ptr + (s->start_addr * 4);
 
-    /* total width & height */
-    cheight = (s->cr[9] & 0x1f) + 1;
-    cw = 8;
-    if (!(s->sr[1] & 0x01))
-        cw = 9;
-    if (s->sr[1] & 0x08)
-        cw = 16; /* NOTE: no 18 pixel wide */
-    x_incr = cw * ((s->ds->depth + 7) >> 3);
-    width = (s->cr[0x01] + 1);
-    if (s->cr[0x06] == 100) {
-        /* ugly hack for CGA 160x100x16 - explain me the logic */
-        height = 100;
-    } else {
-        height = s->cr[0x12] |
-            ((s->cr[0x07] & 0x02) << 7) |
-            ((s->cr[0x07] & 0x40) << 3);
-        height = (height + 1) / cheight;
-    }
-    if ((height * width) > CH_ATTR_SIZE) {
-        /* better than nothing: exit if transient size is too big */
-        return;
-    }
-
-    if (width != s->last_width || height != s->last_height ||
-        cw != s->last_cw || cheight != s->last_ch) {
-        s->last_scr_width = width * cw;
-        s->last_scr_height = height * cheight;
-        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height, s->last_scr_width * (s->ds->depth / 8));
-        s->last_width = width;
-        s->last_height = height;
-        s->last_ch = cheight;
-        s->last_cw = cw;
-        full_update = 1;
-    }
     cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
     if (cursor_offset != s->cursor_offset ||
         s->cr[0xa] != s->cursor_start ||
@@ -1504,16 +1509,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
     s->get_resolution(s, &width, &height);
     disp_width = width;
 
-    ds_depth = s->ds->depth;
-    depth = s->get_bpp(s);
-    if (s->ds->dpy_colourdepth != NULL &&
-            (ds_depth != depth || !s->ds->shared_buf))
-        s->ds->dpy_colourdepth(s->ds, depth);
-    if (ds_depth != s->ds->depth) full_update = 1;
-
-    s->rgb_to_pixel =
-        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
-
     shift_control = (s->gr[0x05] >> 5) & 3;
     double_scan = (s->cr[0x09] >> 7);
     if (shift_control != 1) {
@@ -1530,12 +1525,44 @@ static void vga_draw_graphic(VGAState *s, int full_update)
         s->shift_control = shift_control;
         s->double_scan = double_scan;
     }
+    if (shift_control == 1 && (s->sr[0x01] & 8)) {
+        disp_width <<= 1;
+    }
+
+    ds_depth = s->ds->depth;
+    depth = s->get_bpp(s);
+    if (s->ds->dpy_resize_shared) {
+        if (s->line_offset != s->last_line_offset || 
+            disp_width != s->last_width ||
+            height != s->last_height ||
+            old_depth != depth) {
+            dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));
+            s->last_scr_width = disp_width;
+            s->last_scr_height = height;
+            s->last_width = disp_width;
+            s->last_height = height;
+            s->last_line_offset = s->line_offset;
+            old_depth = depth;
+            full_update = 1;
+        } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
+            s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
+    } else if (disp_width != s->last_width ||
+               height != s->last_height) {
+        dpy_resize(s->ds, disp_width, height);
+        s->last_scr_width = disp_width;
+        s->last_scr_height = height;
+        s->last_width = disp_width;
+        s->last_height = height;
+        full_update = 1;
+    }
+
+    s->rgb_to_pixel = 
+        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
 
     if (shift_control == 0) {
         full_update |= update_palette16(s);
         if (s->sr[0x01] & 8) {
             v = VGA_DRAW_LINE4D2;
-            disp_width <<= 1;
         } else {
             v = VGA_DRAW_LINE4;
         }
@@ -1544,7 +1571,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
         full_update |= update_palette16(s);
         if (s->sr[0x01] & 8) {
             v = VGA_DRAW_LINE2D2;
-            disp_width <<= 1;
         } else {
             v = VGA_DRAW_LINE2;
         }
@@ -1582,19 +1608,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
     }
 
     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
-    if (s->line_offset != s->last_line_offset ||
-        disp_width != s->last_width ||
-        height != s->last_height) {
-        dpy_resize(s->ds, disp_width, height, s->line_offset);
-        s->last_scr_width = disp_width;
-        s->last_scr_height = height;
-        s->last_width = disp_width;
-        s->last_height = height;
-        s->last_line_offset = s->line_offset;
-        full_update = 1;
-    }
-    if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
-        s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
     if (!s->ds->shared_buf && s->cursor_invalidate)
         s->cursor_invalidate(s);
 
index 5a42ba32be673cc51ddd1b4f2979e8be6afd4133..ca1ab65c64cf7ee2cc82c7eda1daf87f9d2edfe8 100644 (file)
@@ -500,7 +500,7 @@ static int xenfb_configure_fb(struct xenfb *xenfb, size_t fb_len_lim,
                        fb_len_lim, fb_len_max);
                fb_len_lim = fb_len_max;
        }
-       if (fb_len > fb_len_lim) {
+       if (fb_len_lim && fb_len > fb_len_lim) {
                fprintf(stderr,
                        "FB: frontend fb size %zu limited to %zu\n",
                        fb_len, fb_len_lim);
@@ -589,10 +589,10 @@ static void xenfb_on_fb_event(struct xenfb *xenfb)
                                               event->resize.offset,
                                               event->resize.stride) < 0)
                                break;
-                       dpy_colourdepth(xenfb->ds, xenfb->depth);
-                       dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
-                       if (xenfb->ds->shared_buf)
-                               dpy_setdata(xenfb->ds, xenfb->pixels + xenfb->offset);
+                       if (xenfb->ds->dpy_resize_shared)
+                           dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
+                       else
+                           dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
                        xenfb_invalidate(xenfb);
                        break;
                }
@@ -1326,10 +1326,10 @@ static int xenfb_register_console(struct xenfb *xenfb) {
                             xenfb_invalidate,
                             xenfb_screen_dump,
                             xenfb);
-       dpy_colourdepth(xenfb->ds, xenfb->depth);
-        dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
-       if (xenfb->ds->shared_buf)
-           dpy_setdata(xenfb->ds, xenfb->pixels);
+        if (xenfb->ds->dpy_resize_shared)
+            dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
+        else
+            dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
 
        if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
                return -1;
@@ -1355,6 +1355,8 @@ static char *kbd_path, *fb_path;
 
 static unsigned char linux2scancode[KEY_MAX + 1];
 
+static void xenfb_pv_colourdepth(DisplayState *ds, int depth);
+
 int xenfb_connect_vkbd(const char *path)
 {
     kbd_path = strdup(path);
@@ -1376,11 +1378,13 @@ static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
     fbfront_update(fb_dev, x, y, w, h);
 }
 
-static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize)
+static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
 {
     XenFBState *xs = ds->opaque;
     struct fbfront_dev *fb_dev = xs->fb_dev;
+    int offset;
     fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize);
+    xenfb_pv_colourdepth(ds, depth);
     ds->width = w;
     ds->height = h;
     if (!linesize)
@@ -1391,13 +1395,20 @@ static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize)
     if (!fb_dev)
         return;
     if (ds->shared_buf) {
-        ds->data = NULL;
+        offset = pixels - xs->vga_vram;
+        ds->data = pixels;
+        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
     } else {
         ds->data = xs->nonshared_vram;
         fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
     }
 }
 
+static void xenfb_pv_resize(DisplayState *ds, int w, int h)
+{
+    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
+}
+
 static void xenfb_pv_colourdepth(DisplayState *ds, int depth)
 {
     XenFBState *xs = ds->opaque;
@@ -1599,7 +1610,7 @@ int xenfb_pv_display_init(DisplayState *ds)
     ds->linesize = 640 * 4;
     ds->dpy_update = xenfb_pv_update;
     ds->dpy_resize = xenfb_pv_resize;
-    ds->dpy_colourdepth = xenfb_pv_colourdepth;
+    ds->dpy_resize_shared = xenfb_pv_resize_shared;
     ds->dpy_setdata = xenfb_pv_setdata;
     ds->dpy_refresh = xenfb_pv_refresh;
     return 0;
index 4545372ca7307824250f9578ba71a458ed4e5fb9..797e6aba0a6b95ad1f8da8f8d54f8d717020287e 100644 (file)
@@ -142,8 +142,12 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 /* called from main_cpu_reset */
 void cpu_reset(CPUX86State *env)
 {
+    extern int s3_shutdown_flag;
     int xcHandle;
     int sts;
+    if (s3_shutdown_flag)
+        return;
 
     xcHandle = xc_interface_open();
     if (xcHandle < 0)
diff --git a/sdl.c b/sdl.c
index 71591c36420b2960456a6b961ebdf841f7033254..4ee35e663bacbd47890cef164a7aac4416e8018e 100644 (file)
--- a/sdl.c
+++ b/sdl.c
@@ -53,6 +53,8 @@ static SDL_Cursor *sdl_cursor_hidden;
 static int absolute_enabled = 0;
 static int opengl_enabled;
 
+static void sdl_colourdepth(DisplayState *ds, int depth);
+
 #ifdef CONFIG_OPENGL
 static GLint tex_format;
 static GLint tex_type;
@@ -190,12 +192,14 @@ static void sdl_setdata(DisplayState *ds, void *pixels)
     ds->data = pixels;
 }
 
-static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
+static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
 {
     int flags;
 
     //    printf("resizing to %d %d\n", w, h);
 
+    sdl_colourdepth(ds, depth);
+
 #ifdef CONFIG_OPENGL
     if (ds->shared_buf && opengl_enabled)
         flags = SDL_OPENGL|SDL_RESIZABLE;
@@ -223,7 +227,8 @@ static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
             opengl_enabled = 0;
             ds->dpy_update = sdl_update;
             ds->dpy_setdata = sdl_setdata;
-            sdl_resize(ds, w, h, linesize);
+            ds->dpy_resize_shared = sdl_resize_shared;
+            sdl_resize_shared(ds, w, h, depth, linesize, pixels);
             return;
         }
         exit(1);
@@ -250,6 +255,7 @@ static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
         } else {
             ds->bgr = 0;
         }
+        shared = NULL;
         ds->data = screen->pixels;
         ds->linesize = screen->pitch;
     } else {
@@ -274,18 +280,26 @@ static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
         };
 #endif
     }
+    if (ds->shared_buf) ds->dpy_setdata(ds, pixels);
+}
+
+static void sdl_resize(DisplayState *ds, int w, int h)
+{
+    sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
 }
 
 static void sdl_colourdepth(DisplayState *ds, int depth)
 {
-    if (!depth || !ds->depth) return;
+    if (!depth || !ds->depth) {
+       ds->shared_buf = 0;
+       ds->dpy_update = sdl_update;
+       return;
+    }
     ds->shared_buf = 1;
     ds->depth = depth;
-    ds->linesize = width * depth / 8;
 #ifdef CONFIG_OPENGL
     if (opengl_enabled) {
         ds->dpy_update = opengl_update;
-        ds->dpy_setdata = opengl_setdata;
     }
 #endif
 }
@@ -501,8 +515,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int state)
 static void toggle_full_screen(DisplayState *ds)
 {
     gui_fullscreen = !gui_fullscreen;
-    sdl_resize(ds, ds->width, ds->height, ds->linesize);
-    ds->dpy_setdata(ds, ds->data);
+    sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data);
     if (gui_fullscreen) {
         gui_saved_grab = gui_grab;
         sdl_grab_start();
@@ -760,11 +773,16 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame, int openg
 
     ds->dpy_update = sdl_update;
     ds->dpy_resize = sdl_resize;
+    ds->dpy_resize_shared = sdl_resize_shared;
     ds->dpy_refresh = sdl_refresh;
-    ds->dpy_colourdepth = sdl_colourdepth;
-    ds->dpy_setdata = sdl_setdata;
+#ifdef CONFIG_OPENGL
+    if (opengl_enabled)
+        ds->dpy_setdata = opengl_setdata;
+    else
+        ds->dpy_setdata = sdl_setdata;
+#endif
 
-    sdl_resize(ds, 640, 400, 640 * 4);
+    sdl_resize(ds, 640, 400);
     sdl_update_caption();
     SDL_EnableKeyRepeat(250, 50);
     gui_grab = 0;
diff --git a/vga-patch-from-xen-unstable-17737:c93a913c221f b/vga-patch-from-xen-unstable-17737:c93a913c221f
new file mode 100644 (file)
index 0000000..b09271b
--- /dev/null
@@ -0,0 +1,577 @@
+diff -r c93a913c221f tools/ioemu/cocoa.m
+--- a/tools/ioemu/cocoa.m      Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/cocoa.m      Wed Jun 04 17:39:37 2008 +0100
+@@ -96,7 +96,7 @@ static void cocoa_update(DisplayState *d
+     cocoa_resize
+  ------------------------------------------------------
+ */
+-static void cocoa_resize(DisplayState *ds, int w, int h, int linesize)
++static void cocoa_resize(DisplayState *ds, int w, int h)
+ {
+     const int device_bpp = 32;
+     static void *screen_pixels;
+diff -r c93a913c221f tools/ioemu/hw/pl110.c
+--- a/tools/ioemu/hw/pl110.c   Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/hw/pl110.c   Wed Jun 04 17:39:37 2008 +0100
+@@ -262,7 +262,7 @@ static void pl110_resize(pl110_state *s,
+ {
+     if (width != s->cols || height != s->rows) {
+         if (pl110_enabled(s)) {
+-            dpy_resize(s->ds, width, height, width * 4);
++            dpy_resize(s->ds, width, height);
+         }
+     }
+     s->cols = width;
+@@ -375,7 +375,7 @@ static void pl110_write(void *opaque, ta
+         s->cr = val;
+         s->bpp = (val >> 1) & 7;
+         if (pl110_enabled(s)) {
+-            dpy_resize(s->ds, s->cols, s->rows, s->cols * 4);
++            dpy_resize(s->ds, s->cols, s->rows);
+         }
+         break;
+     case 10: /* LCDICR */
+diff -r c93a913c221f tools/ioemu/hw/tcx.c
+--- a/tools/ioemu/hw/tcx.c     Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/hw/tcx.c     Wed Jun 04 17:39:37 2008 +0100
+@@ -342,7 +342,7 @@ void tcx_init(DisplayState *ds, uint32_t
+     register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
+     qemu_register_reset(tcx_reset, s);
+     tcx_reset(s);
+-    dpy_resize(s->ds, width, height, width * 1);
++    dpy_resize(s->ds, width, height);
+ }
+ static void tcx_screen_dump(void *opaque, const char *filename)
+diff -r c93a913c221f tools/ioemu/hw/vga.c
+--- a/tools/ioemu/hw/vga.c     Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/hw/vga.c     Wed Jun 04 17:39:37 2008 +0100
+@@ -1065,6 +1065,8 @@ typedef unsigned int rgb_to_pixel_dup_fu
+ static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];
++static int old_depth = 0;
++
+ /* 
+  * Text mode update 
+  * Missing:
+@@ -1089,40 +1091,6 @@ static void vga_draw_text(VGAState *s, i
+     /* Disable dirty bit tracking */
+     xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
+-    if (s->ds->dpy_colourdepth != NULL && s->ds->depth != 0)
+-        s->ds->dpy_colourdepth(s->ds, 0);
+-    s->rgb_to_pixel = 
+-        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
+-
+-    full_update |= update_palette16(s);
+-    palette = s->last_palette;
+-    
+-    /* compute font data address (in plane 2) */
+-    v = s->sr[3];
+-    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
+-    if (offset != s->font_offsets[0]) {
+-        s->font_offsets[0] = offset;
+-        full_update = 1;
+-    }
+-    font_base[0] = s->vram_ptr + offset;
+-
+-    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
+-    font_base[1] = s->vram_ptr + offset;
+-    if (offset != s->font_offsets[1]) {
+-        s->font_offsets[1] = offset;
+-        full_update = 1;
+-    }
+-    if (s->plane_updated & (1 << 2)) {
+-        /* if the plane 2 was modified since the last display, it
+-           indicates the font may have been modified */
+-        s->plane_updated = 0;
+-        full_update = 1;
+-    }
+-    full_update |= update_basic_params(s);
+-
+-    line_offset = s->line_offset;
+-    s1 = s->vram_ptr + (s->start_addr * 4);
+-
+     /* total width & height */
+     cheight = (s->cr[9] & 0x1f) + 1;
+     cw = 8;
+@@ -1130,7 +1098,6 @@ static void vga_draw_text(VGAState *s, i
+         cw = 9;
+     if (s->sr[1] & 0x08)
+         cw = 16; /* NOTE: no 18 pixel wide */
+-    x_incr = cw * ((s->ds->depth + 7) >> 3);
+     width = (s->cr[0x01] + 1);
+     if (s->cr[0x06] == 100) {
+         /* ugly hack for CGA 160x100x16 - explain me the logic */
+@@ -1146,17 +1113,55 @@ static void vga_draw_text(VGAState *s, i
+         return;
+     }
+-    if (width != s->last_width || height != s->last_height ||
++    s->last_scr_width = width * cw;
++    s->last_scr_height = height * cheight;
++    if (s->ds->dpy_resize_shared && old_depth) {
++        dpy_resize_shared(s->ds, s->last_scr_width, s->last_scr_height, 0, s->last_scr_width * (s->ds->depth / 8), NULL);
++        old_depth = 0;
++        full_update = 1;
++    } else if (width != s->last_width || height != s->last_height ||
+         cw != s->last_cw || cheight != s->last_ch) {
+-        s->last_scr_width = width * cw;
+-        s->last_scr_height = height * cheight;
+-        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height, s->last_scr_width * (s->ds->depth / 8));
+-        s->last_width = width;
+-        s->last_height = height;
+-        s->last_ch = cheight;
+-        s->last_cw = cw;
++        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
+         full_update = 1;
+     }
++    s->last_width = width;
++    s->last_height = height;
++    s->last_ch = cheight;
++    s->last_cw = cw;
++
++    s->rgb_to_pixel = 
++        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
++
++    full_update |= update_palette16(s);
++    palette = s->last_palette;
++    
++    x_incr = cw * ((s->ds->depth + 7) >> 3);
++    /* compute font data address (in plane 2) */
++    v = s->sr[3];
++    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
++    if (offset != s->font_offsets[0]) {
++        s->font_offsets[0] = offset;
++        full_update = 1;
++    }
++    font_base[0] = s->vram_ptr + offset;
++
++    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
++    font_base[1] = s->vram_ptr + offset;
++    if (offset != s->font_offsets[1]) {
++        s->font_offsets[1] = offset;
++        full_update = 1;
++    }
++    if (s->plane_updated & (1 << 2)) {
++        /* if the plane 2 was modified since the last display, it
++           indicates the font may have been modified */
++        s->plane_updated = 0;
++        full_update = 1;
++    }
++    full_update |= update_basic_params(s);
++
++    line_offset = s->line_offset;
++    s1 = s->vram_ptr + (s->start_addr * 4);
++
+     cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
+     if (cursor_offset != s->cursor_offset ||
+         s->cr[0xa] != s->cursor_start ||
+@@ -1501,16 +1506,6 @@ static void vga_draw_graphic(VGAState *s
+     s->get_resolution(s, &width, &height);
+     disp_width = width;
+-    ds_depth = s->ds->depth;
+-    depth = s->get_bpp(s);
+-    if (s->ds->dpy_colourdepth != NULL && 
+-            (ds_depth != depth || !s->ds->shared_buf))
+-        s->ds->dpy_colourdepth(s->ds, depth);
+-    if (ds_depth != s->ds->depth) full_update = 1;
+-
+-    s->rgb_to_pixel = 
+-        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
+-
+     shift_control = (s->gr[0x05] >> 5) & 3;
+     double_scan = (s->cr[0x09] >> 7);
+     if (shift_control != 1) {
+@@ -1527,12 +1522,44 @@ static void vga_draw_graphic(VGAState *s
+         s->shift_control = shift_control;
+         s->double_scan = double_scan;
+     }
+-    
++    if (shift_control == 1 && (s->sr[0x01] & 8)) {
++        disp_width <<= 1;
++    }
++
++    ds_depth = s->ds->depth;
++    depth = s->get_bpp(s);
++    if (s->ds->dpy_resize_shared) {
++        if (s->line_offset != s->last_line_offset || 
++            disp_width != s->last_width ||
++            height != s->last_height ||
++            old_depth != depth) {
++            dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));
++            s->last_scr_width = disp_width;
++            s->last_scr_height = height;
++            s->last_width = disp_width;
++            s->last_height = height;
++            s->last_line_offset = s->line_offset;
++            old_depth = depth;
++            full_update = 1;
++        } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
++            s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
++    } else if (disp_width != s->last_width ||
++               height != s->last_height) {
++        dpy_resize(s->ds, disp_width, height);
++        s->last_scr_width = disp_width;
++        s->last_scr_height = height;
++        s->last_width = disp_width;
++        s->last_height = height;
++        full_update = 1;
++    }
++
++    s->rgb_to_pixel = 
++        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
++
+     if (shift_control == 0) {
+         full_update |= update_palette16(s);
+         if (s->sr[0x01] & 8) {
+             v = VGA_DRAW_LINE4D2;
+-            disp_width <<= 1;
+         } else {
+             v = VGA_DRAW_LINE4;
+         }
+@@ -1541,7 +1568,6 @@ static void vga_draw_graphic(VGAState *s
+         full_update |= update_palette16(s);
+         if (s->sr[0x01] & 8) {
+             v = VGA_DRAW_LINE2D2;
+-            disp_width <<= 1;
+         } else {
+             v = VGA_DRAW_LINE2;
+         }
+@@ -1579,19 +1605,6 @@ static void vga_draw_graphic(VGAState *s
+     }
+     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
+-    if (s->line_offset != s->last_line_offset || 
+-        disp_width != s->last_width ||
+-        height != s->last_height) {
+-        dpy_resize(s->ds, disp_width, height, s->line_offset);
+-        s->last_scr_width = disp_width;
+-        s->last_scr_height = height;
+-        s->last_width = disp_width;
+-        s->last_height = height;
+-        s->last_line_offset = s->line_offset; 
+-        full_update = 1;
+-    }
+-    if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
+-        s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
+     if (!s->ds->shared_buf && s->cursor_invalidate)
+         s->cursor_invalidate(s);
+     
+diff -r c93a913c221f tools/ioemu/hw/xenfb.c
+--- a/tools/ioemu/hw/xenfb.c   Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/hw/xenfb.c   Wed Jun 04 17:39:37 2008 +0100
+@@ -587,10 +587,10 @@ static void xenfb_on_fb_event(struct xen
+                                              event->resize.offset,
+                                              event->resize.stride) < 0)
+                               break;
+-                      dpy_colourdepth(xenfb->ds, xenfb->depth);
+-                      dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
+-                      if (xenfb->ds->shared_buf)
+-                              dpy_setdata(xenfb->ds, xenfb->pixels + xenfb->offset);
++                      if (xenfb->ds->dpy_resize_shared)
++                          dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
++                      else
++                          dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
+                       xenfb_invalidate(xenfb);
+                       break;
+               }
+@@ -1324,10 +1324,10 @@ static int xenfb_register_console(struct
+                            xenfb_invalidate,
+                            xenfb_screen_dump,
+                            xenfb);
+-      dpy_colourdepth(xenfb->ds, xenfb->depth);
+-        dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
+-      if (xenfb->ds->shared_buf)
+-          dpy_setdata(xenfb->ds, xenfb->pixels);
++        if (xenfb->ds->dpy_resize_shared)
++            dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
++        else
++            dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
+       if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
+               return -1;
+@@ -1353,6 +1353,8 @@ static char *kbd_path, *fb_path;
+ static unsigned char linux2scancode[KEY_MAX + 1];
++static void xenfb_pv_colourdepth(DisplayState *ds, int depth);
++
+ int xenfb_connect_vkbd(const char *path)
+ {
+     kbd_path = strdup(path);
+@@ -1374,11 +1376,13 @@ static void xenfb_pv_update(DisplayState
+     fbfront_update(fb_dev, x, y, w, h);
+ }
+-static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize)
++static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
+ {
+     XenFBState *xs = ds->opaque;
+     struct fbfront_dev *fb_dev = xs->fb_dev;
++    int offset;
+     fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize);
++    xenfb_pv_colourdepth(ds, depth);
+     ds->width = w;
+     ds->height = h;
+     if (!linesize)
+@@ -1389,11 +1393,18 @@ static void xenfb_pv_resize(DisplayState
+     if (!fb_dev)
+         return;
+     if (ds->shared_buf) {
+-        ds->data = NULL;
++        offset = pixels - xs->vga_vram;
++        ds->data = pixels;
++        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
+     } else {
+         ds->data = xs->nonshared_vram;
+         fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
+     }
++}
++
++static void xenfb_pv_resize(DisplayState *ds, int w, int h)
++{
++    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
+ }
+ static void xenfb_pv_colourdepth(DisplayState *ds, int depth)
+@@ -1597,7 +1608,7 @@ int xenfb_pv_display_init(DisplayState *
+     ds->linesize = 640 * 4;
+     ds->dpy_update = xenfb_pv_update;
+     ds->dpy_resize = xenfb_pv_resize;
+-    ds->dpy_colourdepth = xenfb_pv_colourdepth;
++    ds->dpy_resize_shared = xenfb_pv_resize_shared;
+     ds->dpy_setdata = xenfb_pv_setdata;
+     ds->dpy_refresh = xenfb_pv_refresh;
+     return 0;
+diff -r c93a913c221f tools/ioemu/sdl.c
+--- a/tools/ioemu/sdl.c        Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/sdl.c        Wed Jun 04 17:39:37 2008 +0100
+@@ -50,6 +50,8 @@ static int absolute_enabled = 0;
+ static int absolute_enabled = 0;
+ static int opengl_enabled;
++static void sdl_colourdepth(DisplayState *ds, int depth);
++
+ #ifdef CONFIG_OPENGL
+ static GLint tex_format;
+ static GLint tex_type;
+@@ -211,11 +213,13 @@ static void sdl_setdata(DisplayState *ds
+     ds->data = pixels;
+ }
+-static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
++static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
+ {
+     int flags;
+     //    printf("resizing to %d %d\n", w, h);
++
++    sdl_colourdepth(ds, depth);
+ #ifdef CONFIG_OPENGL
+     if (ds->shared_buf && opengl_enabled)
+@@ -245,7 +249,8 @@ static void sdl_resize(DisplayState *ds,
+             opengl_enabled = 0;
+             ds->dpy_update = sdl_update;
+             ds->dpy_setdata = sdl_setdata;
+-            sdl_resize(ds, w, h, linesize);
++            ds->dpy_resize_shared = sdl_resize_shared;
++            sdl_resize_shared(ds, w, h, depth, linesize, pixels);
+             return;
+         }
+         exit(1);
+@@ -272,6 +277,7 @@ static void sdl_resize(DisplayState *ds,
+         } else {
+             ds->bgr = 0;
+         }
++        shared = NULL;
+         ds->data = screen->pixels;
+         ds->linesize = screen->pitch;
+     } else {
+@@ -296,21 +302,26 @@ static void sdl_resize(DisplayState *ds,
+         };
+ #endif
+     }
++    if (ds->shared_buf) ds->dpy_setdata(ds, pixels);
++}
++
++static void sdl_resize(DisplayState *ds, int w, int h)
++{
++    sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
+ }
+ static void sdl_colourdepth(DisplayState *ds, int depth)
+ {
+     if (!depth || !ds->depth) {
+         ds->shared_buf = 0;
++        ds->dpy_update = sdl_update;
+         return;
+     }
+     ds->shared_buf = 1;
+     ds->depth = depth;
+-    ds->linesize = width * depth / 8;
+ #ifdef CONFIG_OPENGL
+     if (opengl_enabled) {
+         ds->dpy_update = opengl_update;
+-        ds->dpy_setdata = opengl_setdata;
+     }
+ #endif
+ }
+@@ -517,8 +528,7 @@ static void toggle_full_screen(DisplaySt
+ static void toggle_full_screen(DisplayState *ds)
+ {
+     gui_fullscreen = !gui_fullscreen;
+-    sdl_resize(ds, ds->width, ds->height, ds->linesize);
+-    ds->dpy_setdata(ds, ds->data);
++    sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data);
+     if (gui_fullscreen) {
+         gui_saved_grab = gui_grab;
+         sdl_grab_start();
+@@ -760,11 +770,16 @@ void sdl_display_init(DisplayState *ds, 
+     ds->dpy_update = sdl_update;
+     ds->dpy_resize = sdl_resize;
++    ds->dpy_resize_shared = sdl_resize_shared;
+     ds->dpy_refresh = sdl_refresh;
+-    ds->dpy_colourdepth = sdl_colourdepth;
+-    ds->dpy_setdata = sdl_setdata;
+-
+-    sdl_resize(ds, 640, 400, 640 * 4);
++#ifdef CONFIG_OPENGL
++    if (opengl_enabled)
++        ds->dpy_setdata = opengl_setdata;
++    else
++        ds->dpy_setdata = sdl_setdata;
++#endif
++
++    sdl_resize(ds, 640, 400);
+     sdl_update_caption();
+     SDL_EnableKeyRepeat(250, 50);
+     SDL_EnableUNICODE(1);
+diff -r c93a913c221f tools/ioemu/vl.c
+--- a/tools/ioemu/vl.c Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/vl.c Wed Jun 04 17:39:37 2008 +0100
+@@ -4463,7 +4463,6 @@ void dumb_display_init(DisplayState *ds)
+     ds->depth = 0;
+     ds->dpy_update = dumb_update;
+     ds->dpy_resize = dumb_resize;
+-    ds->dpy_colourdepth = NULL;
+     ds->dpy_refresh = dumb_refresh;
+     ds->gui_timer_interval = 500;
+     ds->idle = 1;
+diff -r c93a913c221f tools/ioemu/vl.h
+--- a/tools/ioemu/vl.h Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/vl.h Wed Jun 04 17:39:37 2008 +0100
+@@ -945,9 +945,9 @@ struct DisplayState {
+     int shared_buf;
+     
+     void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
+-    void (*dpy_resize)(struct DisplayState *s, int w, int h, int linesize);
+-    void (*dpy_colourdepth)(struct DisplayState *s, int depth);
++    void (*dpy_resize)(struct DisplayState *s, int w, int h);
+     void (*dpy_setdata)(DisplayState *s, void *pixels);
++    void (*dpy_resize_shared)(DisplayState *s, int w, int h, int depth, int linesize, void *pixels);
+     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);
+ };
+@@ -957,14 +957,14 @@ static inline void dpy_update(DisplaySta
+     s->dpy_update(s, x, y, w, h);
+ }
+-static inline void dpy_resize(DisplayState *s, int w, int h, int linesize)
+-{
+-    s->dpy_resize(s, w, h, linesize);
+-}
+-
+-static inline void dpy_colourdepth(struct DisplayState *s, int depth)
+-{
+-    s->dpy_colourdepth(s, depth);
++static inline void dpy_resize(DisplayState *s, int w, int h)
++{
++    s->dpy_resize(s, w, h);
++}
++
++static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels)
++{
++    s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
+ }
+ static inline void dpy_setdata(DisplayState *s, void *pixels)
+diff -r c93a913c221f tools/ioemu/vnc.c
+--- a/tools/ioemu/vnc.c        Tue May 27 13:03:05 2008 +0100
++++ b/tools/ioemu/vnc.c        Wed Jun 04 17:39:37 2008 +0100
+@@ -277,6 +277,7 @@ static void dequeue_framebuffer_update(V
+ static void dequeue_framebuffer_update(VncState *vs);
+ static int is_empty_queue(VncState *vs);
+ static void free_queue(VncState *vs);
++static void vnc_colourdepth(DisplayState *ds, int depth);
+ #if 0
+ static inline void vnc_set_bit(uint32_t *d, int k)
+@@ -363,13 +364,14 @@ static void vnc_framebuffer_update(VncSt
+     vnc_write_s32(vs, encoding);
+ }
+-static void vnc_dpy_resize(DisplayState *ds, int w, int h, int linesize)
++static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
+ {
+     static int allocated;
+     int size_changed;
+     VncState *vs = ds->opaque;
+     int o;
++    vnc_colourdepth(ds, depth);
+     if (!ds->shared_buf) {
+         ds->linesize = w * vs->depth;
+         if (allocated)
+@@ -419,6 +421,12 @@ static void vnc_dpy_resize(DisplayState 
+     for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
+       vs->dirty_pixel_shift++;
+     framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
++    if (ds->shared_buf) ds->data = pixels;
++}
++
++static void vnc_dpy_resize(DisplayState *ds, int w, int h)
++{
++    vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
+ }
+ /* fastest code */
+@@ -1640,7 +1648,7 @@ static void vnc_dpy_setdata(DisplayState
+     ds->data = pixels;
+ }
+-static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
++static void vnc_colourdepth(DisplayState *ds, int depth)
+ {
+     int host_big_endian_flag;
+     struct VncState *vs = ds->opaque;
+@@ -1742,8 +1750,6 @@ static void vnc_dpy_colourdepth(DisplayS
+             vs->write_pixels = vnc_write_pixels_generic;
+         }
+     }
+-
+-    vnc_dpy_resize(ds, ds->width, ds->height, ds->linesize);
+ }
+ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
+@@ -2502,14 +2508,14 @@ void vnc_display_init(DisplayState *ds)
+     vs->ds->data = NULL;
+     vs->ds->dpy_update = vnc_dpy_update;
+     vs->ds->dpy_resize = vnc_dpy_resize;
+-    vs->ds->dpy_colourdepth = vnc_dpy_colourdepth;
+     vs->ds->dpy_setdata = vnc_dpy_setdata;
++    vs->ds->dpy_resize_shared = vnc_dpy_resize_shared;
+     vs->ds->dpy_refresh = vnc_dpy_refresh;
+     vs->ds->width = 640;
+     vs->ds->height = 400;
+     vs->ds->linesize = 640 * 4;
+-    vnc_dpy_colourdepth(vs->ds, 24);
++    vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
+ }
+ #if CONFIG_VNC_TLS
diff --git a/vnc.c b/vnc.c
index 4ebe32a921c930ffe27f6bc3d03e3f9f67ef7784..2cf3a31af545c52b1f064d985c1f5d1ceb258819 100644 (file)
--- a/vnc.c
+++ b/vnc.c
@@ -279,6 +279,7 @@ static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h,
 static void dequeue_framebuffer_update(VncState *vs);
 static int is_empty_queue(VncState *vs);
 static void free_queue(VncState *vs);
+static void vnc_colourdepth(DisplayState *ds, int depth);
 
 #if 0
 static inline void vnc_set_bit(uint32_t *d, int k)
@@ -365,13 +366,14 @@ static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
     vnc_write_s32(vs, encoding);
 }
 
-static void vnc_dpy_resize(DisplayState *ds, int w, int h, int linesize)
+static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
 {
     static int allocated;
     int size_changed;
     VncState *vs = ds->opaque;
     int o;
 
+    vnc_colourdepth(ds, depth);
     if (!ds->shared_buf) {
         ds->linesize = w * vs->depth;
         if (allocated)
@@ -421,6 +423,12 @@ static void vnc_dpy_resize(DisplayState *ds, int w, int h, int linesize)
     for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
        vs->dirty_pixel_shift++;
     framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
+    if (ds->shared_buf) ds->data = pixels;
+}
+
+static void vnc_dpy_resize(DisplayState *ds, int w, int h)
+{
+    vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
 }
 
 /* fastest code */
@@ -1648,7 +1656,7 @@ static void vnc_dpy_setdata(DisplayState *ds, void *pixels)
     ds->data = pixels;
 }
 
-static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
+static void vnc_colourdepth(DisplayState *ds, int depth)
 {
     int host_big_endian_flag;
     struct VncState *vs = ds->opaque;
@@ -1750,8 +1758,6 @@ static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
             vs->write_pixels = vnc_write_pixels_generic;
         }
     }
-
-    vnc_dpy_resize(ds, ds->width, ds->height, ds->linesize);
 }
 
 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
@@ -2513,14 +2519,14 @@ void vnc_display_init(DisplayState *ds)
     vs->ds->data = NULL;
     vs->ds->dpy_update = vnc_dpy_update;
     vs->ds->dpy_resize = vnc_dpy_resize;
-    vs->ds->dpy_colourdepth = vnc_dpy_colourdepth;
     vs->ds->dpy_setdata = vnc_dpy_setdata;
+    vs->ds->dpy_resize_shared = vnc_dpy_resize_shared;
     vs->ds->dpy_refresh = NULL;
 
     vs->ds->width = 640;
     vs->ds->height = 400;
     vs->ds->linesize = 640 * 4;
-    vnc_dpy_colourdepth(vs->ds, 24);
+    vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
 }
 
 #if CONFIG_VNC_TLS