Import "DisplayState interface change" from qemu mainstream: the patch
has been adapted to qemu-xen and merged with several following fixes.
The original qemu svn commit is the following:
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6336
c046a42c-6fe2-441c-8c8c-71466251a162
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
diff --git a/console.c b/console.c
--- a/console.c
+++ b/console.c
@@ -1000,20 +1000,16 @@
if (index >= MAX_CONSOLES)
return;
+ active_console->g_width = ds_get_width(active_console->ds);
+ active_console->g_height = ds_get_height(active_console->ds);
s = consoles[index];
if (s) {
+ DisplayState *ds = s->ds;
active_console = s;
- if (s->console_type == TEXT_CONSOLE) {
- if (s->g_width != s->ds->width ||
- s->g_height != s->ds->height) {
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
- text_console_resize(s);
- }
- console_refresh(s);
- } else {
- vga_hw_invalidate();
- }
+ ds->surface = qemu_resize_displaysurface(ds->surface, s->g_width,
+ s->g_height, 32, 4 *
s->g_width);
+ dpy_resize(s->ds);
+ vga_hw_invalidate();
}
}
@@ -1121,15 +1117,6 @@
{
TextConsole *s = (TextConsole *) opaque;
- if (s->g_width != ds_get_width(s->ds) || s->g_height !=
ds_get_height(s->ds)) {
- if (s->console_type == TEXT_CONSOLE_FIXED_SIZE)
- dpy_resize(s->ds, s->g_width, s->g_height);
- else {
- s->g_width = ds_get_width(s->ds);
- s->g_height = ds_get_height(s->ds);
- text_console_resize(s);
- }
- }
console_refresh(s);
}
@@ -1263,8 +1250,8 @@
s->total_height = DEFAULT_BACKSCROLL;
s->x = 0;
s->y = 0;
- s->g_width = s->ds->width;
- s->g_height = s->ds->height;
+ s->g_width = ds_get_width(s->ds);
+ s->g_height = ds_get_height(s->ds);
/* Set text attribute defaults */
s->t_attrib_default.bold = 0;
@@ -1286,26 +1273,191 @@
void qemu_console_resize(QEMUConsole *console, int width, int height)
{
- if (console->g_width != width || console->g_height != height
- || !ds_get_data(console->ds)) {
- console->g_width = width;
- console->g_height = height;
- if (active_console == console) {
- dpy_resize(console->ds, width, height);
- }
+ console->g_width = width;
+ console->g_height = height;
+ if (active_console == console) {
+ DisplayState *ds = console->ds;
+ ds->surface = qemu_resize_displaysurface(ds->surface, width, height,
32, 4 * width);
+ dpy_resize(console->ds);
}
}
void qemu_console_copy(QEMUConsole *console, int src_x, int src_y,
int dst_x, int dst_y, int w, int h)
{
- if (active_console == console) {
- if (console->ds->dpy_copy)
- console->ds->dpy_copy(console->ds,
- src_x, src_y, dst_x, dst_y, w, h);
- else {
- /* TODO */
- console->ds->dpy_update(console->ds, dst_x, dst_y, w, h);
- }
+ if (active_console == console)
+ dpy_copy(console->ds, src_x, src_y, dst_x, dst_y, w, h);
+}
+
+PixelFormat qemu_different_endianness_pixelformat(int bpp)
+{
+ PixelFormat pf;
+
+ memset(&pf, 0x00, sizeof(PixelFormat));
+
+ pf.bits_per_pixel = bpp;
+ pf.bytes_per_pixel = bpp / 8;
+ pf.depth = bpp == 32 ? 24 : bpp;
+
+ switch (bpp) {
+ case 24:
+ pf.rmask = 0x000000FF;
+ pf.gmask = 0x0000FF00;
+ pf.bmask = 0x00FF0000;
+ pf.rmax = 255;
+ pf.gmax = 255;
+ pf.bmax = 255;
+ pf.rshift = 0;
+ pf.gshift = 8;
+ pf.bshift = 16;
+ break;
+ case 32:
+ pf.rmask = 0x0000FF00;
+ pf.gmask = 0x00FF0000;
+ pf.bmask = 0xFF000000;
+ pf.amask = 0x00000000;
+ pf.amax = 255;
+ pf.rmax = 255;
+ pf.gmax = 255;
+ pf.bmax = 255;
+ pf.ashift = 0;
+ pf.rshift = 8;
+ pf.gshift = 16;
+ pf.bshift = 24;
+ break;
+ default:
+ break;
}
+ return pf;
}
+
+PixelFormat qemu_default_pixelformat(int bpp)
+{
+ PixelFormat pf;
+
+ memset(&pf, 0x00, sizeof(PixelFormat));
+
+ pf.bits_per_pixel = bpp;
+ pf.bytes_per_pixel = bpp / 8;
+ pf.depth = bpp == 32 ? 24 : bpp;
+
+ switch (bpp) {
+ case 16:
+ pf.rmask = 0x0000F800;
+ pf.gmask = 0x000007E0;
+ pf.bmask = 0x0000001F;
+ pf.rmax = 31;
+ pf.gmax = 63;
+ pf.bmax = 31;
+ pf.rshift = 11;
+ pf.gshift = 5;
+ pf.bshift = 0;
+ break;
+ case 24:
+ pf.rmask = 0x00FF0000;
+ pf.gmask = 0x0000FF00;
+ pf.bmask = 0x000000FF;
+ pf.rmax = 255;
+ pf.gmax = 255;
+ pf.bmax = 255;
+ pf.rshift = 16;
+ pf.gshift = 8;
+ pf.bshift = 0;
+ case 32:
+ pf.rmask = 0x00FF0000;
+ pf.gmask = 0x0000FF00;
+ pf.bmask = 0x000000FF;
+ pf.amax = 255;
+ pf.rmax = 255;
+ pf.gmax = 255;
+ pf.bmax = 255;
+ pf.ashift = 24;
+ pf.rshift = 16;
+ pf.gshift = 8;
+ pf.bshift = 0;
+ break;
+ default:
+ break;
+ }
+ return pf;
+}
+
+DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int
linesize)
+{
+ DisplaySurface *surface = (DisplaySurface*)
qemu_mallocz(sizeof(DisplaySurface));
+ if (surface == NULL) {
+ fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
+ exit(1);
+ }
+
+ surface->width = width;
+ surface->height = height;
+ surface->linesize = linesize;
+ surface->pf = qemu_default_pixelformat(bpp);
+#ifdef WORDS_BIGENDIAN
+ surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
+#else
+ surface->flags = QEMU_ALLOCATED_FLAG;
+#endif
+ surface->data = (uint8_t*) qemu_mallocz(surface->linesize *
surface->height);
+ if (surface->data == NULL) {
+ fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
+ exit(1);
+ }
+
+ return surface;
+}
+
+DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
+ int width, int height, int bpp, int
linesize)
+{
+ surface->width = width;
+ surface->height = height;
+ surface->linesize = linesize;
+ surface->pf = qemu_default_pixelformat(bpp);
+ if (surface->flags & QEMU_ALLOCATED_FLAG)
+ surface->data = (uint8_t*) qemu_realloc(surface->data,
surface->linesize * surface->height);
+ else
+ surface->data = (uint8_t*) qemu_malloc(surface->linesize *
surface->height);
+ if (surface->data == NULL) {
+ fprintf(stderr, "qemu_resize_displaysurface: malloc failed\n");
+ exit(1);
+ }
+#ifdef WORDS_BIGENDIAN
+ surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
+#else
+ surface->flags = QEMU_ALLOCATED_FLAG;
+#endif
+
+ return surface;
+}
+
+DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
+ int linesize, uint8_t *data)
+{
+ DisplaySurface *surface = (DisplaySurface*)
qemu_mallocz(sizeof(DisplaySurface));
+ if (surface == NULL) {
+ fprintf(stderr, "qemu_create_displaysurface_from: malloc failed\n");
+ exit(1);
+ }
+
+ surface->width = width;
+ surface->height = height;
+ surface->linesize = linesize;
+ surface->pf = qemu_default_pixelformat(bpp);
+#ifdef WORDS_BIGENDIAN
+ surface->flags = QEMU_BIG_ENDIAN_FLAG;
+#endif
+ surface->data = data;
+
+ return surface;
+}
+
+void qemu_free_displaysurface(DisplaySurface *surface)
+{
+ if (surface == NULL)
+ return;
+ if (surface->flags & QEMU_ALLOCATED_FLAG)
+ qemu_free(surface->data);
+ qemu_free(surface);
+}
diff --git a/console.h b/console.h
--- a/console.h
+++ b/console.h
@@ -67,80 +67,170 @@
/* in ms */
#define GUI_REFRESH_INTERVAL 30
+#define QEMU_BIG_ENDIAN_FLAG 0x01
+#define QEMU_ALLOCATED_FLAG 0x02
-struct DisplayState {
- uint8_t *data;
- int linesize;
- int depth;
- int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */
+struct PixelFormat {
+ uint8_t bits_per_pixel;
+ uint8_t bytes_per_pixel;
+ uint8_t depth; /* color depth in bits */
+ uint32_t rmask, gmask, bmask, amask;
+ uint8_t rshift, gshift, bshift, ashift;
+ uint8_t rmax, gmax, bmax, amax;
+};
+
+struct DisplaySurface {
+ uint8_t flags;
int width;
int height;
- void *opaque;
- uint32_t *palette;
- struct QEMUTimer *gui_timer;
+ int linesize; /* bytes per line */
+ uint8_t *data;
+
+ struct PixelFormat pf;
+};
+
+struct DisplayChangeListener {
+ int idle;
uint64_t gui_timer_interval;
- int idle; /* there is nothing to update (window invisible), set by vnc/sdl
*/
- 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);
- void (*dpy_resize_shared)(struct DisplayState *s, int w, int h, int depth,
int linesize, void *pixels);
- void (*dpy_setdata)(DisplayState *s, void *pixels);
+ void (*dpy_resize)(struct DisplayState *s);
+ void (*dpy_setdata)(struct DisplayState *s);
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_fill)(struct DisplayState *s, int x, int y,
int w, int h, uint32_t c);
void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
+
+ struct DisplayChangeListener *next;
};
+
+struct DisplayState {
+ struct DisplaySurface *surface;
+ void *opaque;
+ struct QEMUTimer *gui_timer;
+
+ struct DisplayChangeListener* listeners;
+
+ 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);
+};
+
+DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int
linesize);
+DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
+ int width, int height, int bpp, int
linesize);
+DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
+ int linesize, uint8_t *data);
+void qemu_free_displaysurface(DisplaySurface *surface);
+PixelFormat qemu_different_endianness_pixelformat(int bpp);
+PixelFormat qemu_default_pixelformat(int bpp);
+
+static inline int is_buffer_shared(DisplaySurface *surface)
+{
+ return (!(surface->flags & QEMU_ALLOCATED_FLAG));
+}
+
+static inline void register_displaychangelistener(DisplayState *ds,
DisplayChangeListener *dcl)
+{
+ dcl->next = ds->listeners;
+ ds->listeners = dcl;
+}
static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
{
- s->dpy_update(s, x, y, w, h);
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ dcl->dpy_update(s, x, y, w, h);
+ dcl = dcl->next;
+ }
}
-static inline void dpy_resize(DisplayState *s, int w, int h)
+static inline void dpy_resize(DisplayState *s)
{
- s->dpy_resize(s, w, h);
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ dcl->dpy_resize(s);
+ dcl = dcl->next;
+ }
}
-static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth,
int linesize, void *pixels)
+
+static inline void dpy_setdata(DisplayState *s)
{
- s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_setdata) dcl->dpy_setdata(s);
+ dcl = dcl->next;
+ }
}
-static inline void dpy_cursor(DisplayState *s, int x, int y)
+
+static inline void dpy_refresh(DisplayState *s)
{
- if (s->dpy_text_cursor)
- s->dpy_text_cursor(s, x, y);
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_refresh) dcl->dpy_refresh(s);
+ dcl = dcl->next;
+ }
+}
+
+static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
+ int dst_x, int dst_y, int w, int h) {
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_copy)
+ dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
+ else /* TODO */
+ dcl->dpy_update(s, dst_x, dst_y, w, h);
+ dcl = dcl->next;
+ }
+}
+
+static inline void dpy_fill(struct DisplayState *s, int x, int y,
+ int w, int h, uint32_t c) {
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_fill) dcl->dpy_fill(s, x, y, w, h, c);
+ dcl = dcl->next;
+ }
+}
+
+static inline void dpy_cursor(struct DisplayState *s, int x, int y) {
+ struct DisplayChangeListener *dcl = s->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_text_cursor) dcl->dpy_text_cursor(s, x, y);
+ dcl = dcl->next;
+ }
}
static inline int ds_get_linesize(DisplayState *ds)
{
- return ds->linesize;
+ return ds->surface->linesize;
}
static inline uint8_t* ds_get_data(DisplayState *ds)
{
- return ds->data;
+ return ds->surface->data;
}
static inline int ds_get_width(DisplayState *ds)
{
- return ds->width;
+ return ds->surface->width;
}
static inline int ds_get_height(DisplayState *ds)
{
- return ds->height;
+ return ds->surface->height;
}
static inline int ds_get_bits_per_pixel(DisplayState *ds)
{
- return ds->depth;
+ return ds->surface->pf.bits_per_pixel;
}
static inline int ds_get_bytes_per_pixel(DisplayState *ds)
{
- return (ds->depth / 8);
+ return ds->surface->pf.bytes_per_pixel;
}
typedef unsigned long console_ch_t;
diff --git a/curses.c b/curses.c
--- a/curses.c
+++ b/curses.c
@@ -97,13 +97,13 @@
}
}
-static void curses_resize(DisplayState *ds, int w, int h)
+static void curses_resize(DisplayState *ds)
{
- if (w == gwidth && h == gheight)
+ if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight)
return;
- gwidth = w;
- gheight = h;
+ gwidth = ds_get_width(ds);
+ gheight = ds_get_height(ds);
curses_calc_pad();
}
@@ -169,8 +169,8 @@
clear();
refresh();
curses_calc_pad();
- ds->width = FONT_WIDTH * width;
- ds->height = FONT_HEIGHT * height;
+ ds->surface->width = FONT_WIDTH * width;
+ ds->surface->height = FONT_HEIGHT * height;
vga_hw_invalidate();
invalidate = 0;
}
@@ -197,8 +197,8 @@
refresh();
curses_calc_pad();
curses_update(ds, 0, 0, width, height);
- ds->width = FONT_WIDTH * width;
- ds->height = FONT_HEIGHT * height;
+ ds->surface->width = FONT_WIDTH * width;
+ ds->surface->height = FONT_HEIGHT * height;
continue;
}
#endif
@@ -338,6 +338,7 @@
void curses_display_init(DisplayState *ds, int full_screen)
{
+ DisplayChangeListener *dcl;
#ifndef _WIN32
if (!isatty(1)) {
fprintf(stderr, "We need a terminal output\n");
@@ -357,18 +358,19 @@
#endif
#endif
- ds->data = (void *) screen;
- ds->linesize = 0;
- ds->depth = 0;
- ds->width = 640;
- ds->height = 400;
- ds->dpy_update = curses_update;
- ds->dpy_resize = curses_resize;
- ds->dpy_refresh = curses_refresh;
- ds->dpy_text_cursor = curses_cursor_position;
+ dcl = (DisplayChangeListener *)
qemu_mallocz(sizeof(DisplayChangeListener));
+ if (!dcl)
+ exit(1);
+ dcl->dpy_update = curses_update;
+ dcl->dpy_resize = curses_resize;
+ dcl->dpy_refresh = curses_refresh;
+ dcl->dpy_text_cursor = curses_cursor_position;
+ register_displaychangelistener(ds, dcl);
+ qemu_free_displaysurface(ds->surface);
+ ds->surface = qemu_create_displaysurface_from(80, 25, 0, 0, (uint8_t*)
screen);
invalidate = 1;
/* Standard VGA initial text mode dimensions */
- curses_resize(ds, 80, 25);
+ curses_resize(ds);
}
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -794,26 +794,9 @@
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
{
- if (s->ds->dpy_copy) {
- cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
- s->cirrus_blt_srcaddr - s->start_addr,
- s->cirrus_blt_width, s->cirrus_blt_height);
- } else {
-
- if (BLTUNSAFE(s))
- return 0;
-
- (*s->cirrus_rop) (s, s->vram_ptr +
- (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
- s->vram_ptr +
- (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
- s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
- s->cirrus_blt_width, s->cirrus_blt_height);
-
- cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
- s->cirrus_blt_dstpitch, s->cirrus_blt_width,
- s->cirrus_blt_height);
- }
+ cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
+ s->cirrus_blt_srcaddr - s->start_addr,
+ s->cirrus_blt_width, s->cirrus_blt_height);
return 1;
}
diff --git a/hw/nseries.c b/hw/nseries.c
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1361,7 +1361,8 @@
/* FIXME: We shouldn't really be doing this here. The LCD controller
will set the size once configured, so this just sets an initial
size until the guest activates the display. */
- dpy_resize(ds, 800, 480);
+ ds->surface = qemu_resize_displaysurface(ds->surface, 800, 480, 32, 4 *
800);
+ dpy_resize(ds);
}
static struct arm_boot_info n800_binfo = {
diff --git a/hw/palm.c b/hw/palm.c
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -278,7 +278,8 @@
/* FIXME: We shouldn't really be doing this here. The LCD controller
will set the size once configured, so this just sets an initial
size until the guest activates the display. */
- dpy_resize(ds, 320, 320);
+ ds->surface = qemu_resize_displaysurface(ds->surface, 320, 320, 32, 4 *
320);
+ dpy_resize(ds);
}
QEMUMachine palmte_machine = {
diff --git a/hw/vga.c b/hw/vga.c
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1270,18 +1270,19 @@
return;
}
- s->last_scr_width = width * cw;
- s->last_scr_height = height * cheight;
if (width != s->last_width || height != s->last_height ||
cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
- dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
+ s->last_scr_width = width * cw;
+ s->last_scr_height = height * cheight;
+ qemu_console_resize(s->console, s->last_scr_width, s->last_scr_height);
+ dpy_resize(s->ds);
s->last_depth = 0;
+ s->last_width = width;
+ s->last_height = height;
+ s->last_ch = cheight;
+ s->last_cw = cw;
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)];
@@ -1289,7 +1290,7 @@
full_update |= update_palette16(s);
palette = s->last_palette;
- x_incr = cw * ((s->ds->depth + 7) >> 3);
+ x_incr = cw * ds_get_bytes_per_pixel(s->ds);
/* compute font data address (in plane 2) */
v = s->sr[3];
offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
@@ -1323,7 +1324,7 @@
cw = 9;
if (s->sr[1] & 0x08)
cw = 16; /* NOTE: no 18 pixel wide */
- x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
+ x_incr = cw * ds_get_bytes_per_pixel(s->ds);
width = (s->cr[0x01] + 1);
if (s->cr[0x06] == 100) {
/* ugly hack for CGA 160x100x16 - explain me the logic */
@@ -1616,31 +1617,43 @@
disp_width <<= 1;
}
- ds_depth = s->ds->depth;
+ ds_depth = ds_get_bits_per_pixel(s->ds);
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 ||
- s->last_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;
- s->last_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);
+ 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->surface);
+ s->ds->surface = qemu_create_displaysurface_from(disp_width,
height, depth,
+ s->line_offset,
+ s->vram_ptr +
(s->start_addr * 4));
+#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+ s->ds->surface->pf =
qemu_different_endianness_pixelformat(depth);
+#endif
+ dpy_resize(s->ds);
+ } else {
+ qemu_console_resize(s->console, disp_width, height);
+ }
+ } else {
+ qemu_console_resize(s->console, disp_width, height);
+ }
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;
+ s->last_depth = depth;
full_update = 1;
+ } else if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&
+ (full_update || s->ds->surface->data != s->vram_ptr +
(s->start_addr * 4))) {
+ s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
+ dpy_setdata(s->ds);
}
s->rgb_to_pixel =
@@ -1695,7 +1708,7 @@
}
vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
get_depth_index(s->ds)];
- if (!s->ds->shared_buf && s->cursor_invalidate)
+ if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)
s->cursor_invalidate(s);
line_offset = s->line_offset;
@@ -1756,8 +1769,8 @@
y_start = -1;
page_min = 0;
page_max = 0;
- d = s->ds->data;
- linesize = s->ds->linesize;
+ d = ds_get_data(s->ds);
+ linesize = ds_get_linesize(s->ds);
y1 = 0;
for(y = 0; y < height; y++) {
addr = addr1;
@@ -1789,7 +1802,7 @@
page_min = page0;
if (page_max == 0 || page1 > page_max)
page_max = page1;
- if (!s->ds->shared_buf) {
+ if (!is_buffer_shared(s->ds->surface)) {
vga_draw_line(s, d, s->vram_ptr + addr, width);
if (s->cursor_draw_line)
s->cursor_draw_line(s, d, y);
@@ -1844,15 +1857,15 @@
s->rgb_to_pixel =
rgb_to_pixel_dup_table[get_depth_index(s->ds)];
- if (s->ds->depth == 8)
+ if (ds_get_bits_per_pixel(s->ds) == 8)
val = s->rgb_to_pixel(0, 0, 0);
else
val = 0;
- w = s->last_scr_width * ((s->ds->depth + 7) >> 3);
- d = s->ds->data;
+ w = s->last_scr_width * ds_get_bytes_per_pixel(s->ds);
+ d = ds_get_data(s->ds);
for(i = 0; i < s->last_scr_height; i++) {
memset(d, val, w);
- d += s->ds->linesize;
+ d += ds_get_linesize(s->ds);
}
dpy_update(s->ds, 0, 0,
s->last_scr_width, s->last_scr_height);
@@ -1977,7 +1990,9 @@
cw != s->last_cw || cheight != s->last_ch) {
s->last_scr_width = width * cw;
s->last_scr_height = height * cheight;
- qemu_console_resize(s->console, width, height);
+ s->ds->surface->width = width;
+ s->ds->surface->height = height;
+ dpy_resize(s->ds);
s->last_width = width;
s->last_height = height;
s->last_ch = cheight;
@@ -2058,7 +2073,9 @@
s->last_width = 60;
s->last_height = height = 3;
dpy_cursor(s->ds, -1, -1);
- qemu_console_resize(s->console, s->last_width, height);
+ s->ds->surface->width = s->last_width;
+ s->ds->surface->height = height;
+ dpy_resize(s->ds);
for (dst = chardata, i = 0; i < s->last_width * height; i ++)
console_write_ch(dst ++, ' ');
@@ -2520,7 +2537,6 @@
s->vram_offset = vga_ram_offset;
s->vram_size = vga_ram_size;
s->ds = ds;
- ds->palette = s->last_palette;
s->get_bpp = vga_get_bpp;
s->get_offsets = vga_get_offsets;
s->get_resolution = vga_get_resolution;
@@ -2690,12 +2706,8 @@
{
}
-static void vga_save_dpy_resize(DisplayState *s, int w, int h)
+static void vga_save_dpy_resize(DisplayState *s)
{
- s->linesize = w * 4;
- s->data = qemu_mallocz(h * s->linesize);
- vga_save_w = w;
- vga_save_h = h;
}
static void vga_save_dpy_refresh(DisplayState *s)
@@ -2737,25 +2749,28 @@
{
VGAState *s = (VGAState *)opaque;
DisplayState *saved_ds, ds1, *ds = &ds1;
+ DisplayChangeListener dcl;
/* XXX: this is a little hackish */
vga_invalidate_display(s);
saved_ds = s->ds;
memset(ds, 0, sizeof(DisplayState));
- ds->dpy_update = vga_save_dpy_update;
- ds->dpy_resize = vga_save_dpy_resize;
- ds->dpy_refresh = vga_save_dpy_refresh;
- ds->depth = 32;
-
+ memset(&dcl, 0, sizeof(DisplayChangeListener));
+ dcl.dpy_update = vga_save_dpy_update;
+ dcl.dpy_resize = vga_save_dpy_resize;
+ dcl.dpy_refresh = vga_save_dpy_refresh;
+ register_displaychangelistener(ds, &dcl);
+ ds->surface = qemu_create_displaysurface(ds_get_width(saved_ds),
+ ds_get_height(saved_ds), 32, 4 * ds_get_width(saved_ds));
+
s->ds = ds;
s->graphic_mode = -1;
vga_update_display(s);
- if (ds_get_data(ds)) {
- ppm_save(filename, ds_get_data(ds), vga_save_w, vga_save_h,
- ds_get_linesize(s->ds));
- qemu_free(ds_get_data(ds));
- }
+ ppm_save(filename, ds_get_data(ds), vga_save_w, vga_save_h,
+ ds_get_linesize(ds));
+
+ qemu_free_displaysurface(ds->surface);
s->ds = saved_ds;
}
diff --git a/hw/xenfb.c b/hw/xenfb.c
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -700,21 +700,30 @@
{
struct XenFB *xenfb = opaque;
int i;
+ struct DisplayChangeListener *l;
if (xenfb->feature_update) {
#ifdef XENFB_TYPE_REFRESH_PERIOD
- int period;
+ int period = 99999999;
+ int idle = 1;
if (xenfb_queue_full(xenfb))
return;
- if (xenfb->c.ds->idle)
- period = XENFB_NO_REFRESH;
- else {
- period = xenfb->c.ds->gui_timer_interval;
- if (!period)
- period = GUI_REFRESH_INTERVAL;
- }
+ for (l = xenfb->c.ds->listeners; l != NULL; l = l->next) {
+ if (l->idle)
+ continue;
+ idle = 0;
+ if (!l->gui_timer_interval) {
+ if (period > GUI_REFRESH_INTERVAL)
+ period = GUI_REFRESH_INTERVAL;
+ } else {
+ if (period > l->gui_timer_interval)
+ period = l->gui_timer_interval;
+ }
+ }
+ if (idle)
+ period = XENFB_NO_REFRESH;
if (xenfb->refresh_period != period) {
xenfb_send_refresh_period(xenfb, period);
@@ -733,7 +742,9 @@
if (xenfb->width != ds_get_width(xenfb->c.ds) || xenfb->height !=
ds_get_height(xenfb->c.ds)) {
xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d\n",
xenfb->width, xenfb->height);
- dpy_resize(xenfb->c.ds, xenfb->width, xenfb->height);
+ xenfb->c.ds->surface->width = xenfb->width;
+ xenfb->c.ds->surface->height = xenfb->height;
+ dpy_resize(xenfb->c.ds);
xenfb->up_fullscreen = 1;
}
diff --git a/qemu-common.h b/qemu-common.h
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -131,6 +131,9 @@
typedef struct AudioState AudioState;
typedef struct BlockDriverState BlockDriverState;
typedef struct DisplayState DisplayState;
+typedef struct DisplayChangeListener DisplayChangeListener;
+typedef struct DisplaySurface DisplaySurface;
+typedef struct PixelFormat PixelFormat;
typedef struct TextConsole TextConsole;
typedef TextConsole QEMUConsole;
typedef struct CharDriverState CharDriverState;
diff --git a/sdl.c b/sdl.c
--- a/sdl.c
+++ b/sdl.c
@@ -35,8 +35,9 @@
#include <SDL_opengl.h>
#endif
-static SDL_Surface *screen;
-static SDL_Surface *shared = NULL;
+static DisplayChangeListener *dcl;
+static SDL_Surface *real_screen;
+static SDL_Surface *guest_screen = NULL;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
static int last_vm_running;
static int gui_saved_grab;
@@ -52,17 +53,15 @@
static SDL_Cursor *sdl_cursor_hidden;
static int absolute_enabled = 0;
static int opengl_enabled;
-static uint8_t bgr;
-
-static void sdl_colourdepth(DisplayState *ds, int depth);
#ifdef CONFIG_OPENGL
static GLint tex_format;
static GLint tex_type;
static GLuint texture_ref = 0;
static GLint gl_format;
+static uint8_t bgr;
-static void opengl_setdata(DisplayState *ds, void *pixels)
+static void opengl_setdata(DisplayState *ds)
{
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -72,14 +71,13 @@
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
- glViewport( 0, 0, screen->w, screen->h);
+ glViewport( 0, 0, real_screen->w, real_screen->h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0, screen->w, screen->h, 0, -1,1);
+ glOrtho(0, real_screen->w, real_screen->h, 0, -1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
- ds->data = pixels;
if (texture_ref) {
glDeleteTextures(1, &texture_ref);
@@ -90,27 +88,6 @@
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_ref);
glPixelStorei(GL_UNPACK_LSB_FIRST, 1);
switch (ds_get_bits_per_pixel(ds)) {
- case 8:
- if (ds->palette == NULL) {
- tex_format = GL_RGB;
- tex_type = GL_UNSIGNED_BYTE_3_3_2;
- } else {
- int i;
- GLushort paletter[256], paletteg[256], paletteb[256];
- for (i = 0; i < 256; i++) {
- uint8_t rgb = ds->palette[i] >> 16;
- paletter[i] = ((rgb & 0xe0) >> 5) * 65535 / 7;
- paletteg[i] = ((rgb & 0x1c) >> 2) * 65535 / 7;
- paletteb[i] = (rgb & 0x3) * 65535 / 3;
- }
- glPixelMapusv(GL_PIXEL_MAP_I_TO_R, 256, paletter);
- glPixelMapusv(GL_PIXEL_MAP_I_TO_G, 256, paletteg);
- glPixelMapusv(GL_PIXEL_MAP_I_TO_B, 256, paletteb);
-
- tex_format = GL_COLOR_INDEX;
- tex_type = GL_UNSIGNED_BYTE;
- }
- break;
case 16:
tex_format = GL_RGB;
tex_type = GL_UNSIGNED_SHORT_5_6_5;
@@ -120,7 +97,7 @@
tex_type = GL_UNSIGNED_BYTE;
break;
case 32:
- if (!bgr) {
+ if (bgr == (ds->surface->pf.rshift < ds->surface->pf.bshift)) {
tex_format = GL_BGRA;
tex_type = GL_UNSIGNED_BYTE;
} else {
@@ -130,7 +107,7 @@
break;
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, (ds_get_linesize(ds) /
ds_get_bytes_per_pixel(ds)));
- glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds_get_width(ds),
ds_get_height(ds), 0, tex_format, tex_type, pixels);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_format, ds_get_width(ds),
ds_get_height(ds), 0, tex_format, tex_type, ds_get_data(ds));
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_PRIORITY, 1.0);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
@@ -149,12 +126,12 @@
glBegin(GL_QUADS);
glTexCoord2d(0, 0);
glVertex2d(0, 0);
- glTexCoord2d(ds->width, 0);
- glVertex2d(screen->w, 0);
- glTexCoord2d(ds->width, ds->height);
- glVertex2d(screen->w, screen->h);
- glTexCoord2d(0, ds->height);
- glVertex2d(0, screen->h);
+ glTexCoord2d(ds_get_width(ds), 0);
+ glVertex2d(real_screen->w, 0);
+ glTexCoord2d(ds_get_width(ds), ds_get_height(ds));
+ glVertex2d(real_screen->w, real_screen->h);
+ glTexCoord2d(0, ds_get_height(ds));
+ glVertex2d(0, real_screen->h);
glEnd();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
SDL_GL_SwapBuffers();
@@ -163,130 +140,73 @@
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
{
- // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
- if (shared) {
- SDL_Rect rec;
- rec.x = x;
- rec.y = y;
- rec.w = w;
- rec.h = h;
- SDL_BlitSurface(shared, &rec, screen, &rec);
- }
- SDL_Flip(screen);
+ SDL_Rect rec;
+ rec.x = x;
+ rec.y = y;
+ rec.w = w;
+ rec.h = h;
+ // printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);i
+
+ SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
+ SDL_UpdateRect(real_screen, x, y, w, h);
}
-static void sdl_setdata(DisplayState *ds, void *pixels)
+static void sdl_setdata(DisplayState *ds)
{
- uint32_t rmask, gmask, bmask, amask = 0;
- switch (ds_get_bits_per_pixel(ds)) {
- case 8:
- rmask = 0x000000E0;
- gmask = 0x0000001C;
- bmask = 0x00000003;
- break;
- case 16:
- rmask = 0x0000F800;
- gmask = 0x000007E0;
- bmask = 0x0000001F;
- break;
- case 24:
- rmask = 0x00FF0000;
- gmask = 0x0000FF00;
- bmask = 0x000000FF;
- break;
- case 32:
- rmask = 0x00FF0000;
- gmask = 0x0000FF00;
- bmask = 0x000000FF;
- break;
- default:
- return;
- }
- shared = SDL_CreateRGBSurfaceFrom(pixels, width, height,
ds_get_bits_per_pixel(ds), ds_get_linesize(ds), rmask , gmask, bmask, amask);
- if (ds_get_bits_per_pixel(ds) == 8 && ds->palette != NULL) {
- SDL_Color palette[256];
- int i;
- for (i = 0; i < 256; i++) {
- uint8_t rgb = ds->palette[i] >> 16;
- palette[i].r = ((rgb & 0xe0) >> 5) * 255 / 7;
- palette[i].g = ((rgb & 0x1c) >> 2) * 255 / 7;
- palette[i].b = (rgb & 0x3) * 255 / 3;
- }
- SDL_SetColors(shared, palette, 0, 256);
- }
- ds->data = pixels;
+ SDL_Rect rec;
+ rec.x = 0;
+ rec.y = 0;
+ rec.w = real_screen->w;
+ rec.h = real_screen->h;
+
+ if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
+
+ guest_screen = SDL_CreateRGBSurfaceFrom(ds_get_data(ds), ds_get_width(ds),
ds_get_height(ds),
+ ds_get_bits_per_pixel(ds),
ds_get_linesize(ds),
+ ds->surface->pf.rmask,
ds->surface->pf.gmask,
+ ds->surface->pf.bmask,
ds->surface->pf.amask);
}
-static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int
linesize, void *pixels)
+static void sdl_resize(DisplayState *ds)
{
int flags;
// printf("resizing to %d %d\n", w, h);
-
- sdl_colourdepth(ds, depth);
-
#ifdef CONFIG_OPENGL
- if (ds->shared_buf && opengl_enabled)
+ if (opengl_enabled)
flags = SDL_OPENGL|SDL_RESIZABLE;
else
#endif
- flags =
SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_DOUBLEBUF|SDL_HWPALETTE;
+ flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
- if (gui_fullscreen) {
+ if (gui_fullscreen)
flags |= SDL_FULLSCREEN;
- flags &= ~SDL_RESIZABLE;
- }
if (gui_noframe)
flags |= SDL_NOFRAME;
- width = w;
- height = h;
-
- again:
- screen = SDL_SetVideoMode(w, h, 0, flags);
-
- if (!screen) {
- fprintf(stderr, "Could not open SDL display: %s\n", SDL_GetError());
+ width = ds_get_width(ds);
+ height = ds_get_height(ds);
+ real_screen = SDL_SetVideoMode(width, height, 0, flags);
+ if (!real_screen) {
if (opengl_enabled) {
/* Fallback to SDL */
opengl_enabled = 0;
- ds->dpy_update = sdl_update;
- ds->dpy_setdata = sdl_setdata;
- ds->dpy_resize_shared = sdl_resize_shared;
- sdl_resize_shared(ds, w, h, depth, linesize, pixels);
+ dcl->dpy_update = sdl_update;
+ dcl->dpy_setdata = sdl_setdata;
+ sdl_resize(ds);
return;
}
+ fprintf(stderr, "Could not open SDL display\n");
exit(1);
}
- if (!opengl_enabled) {
- if (!screen->pixels && (flags & SDL_HWSURFACE) && (flags &
SDL_FULLSCREEN)) {
- flags &= ~SDL_HWSURFACE;
- goto again;
- }
-
- if (!screen->pixels) {
- fprintf(stderr, "Could not open SDL display: %s\n",
SDL_GetError());
- exit(1);
- }
+#ifdef CONFIG_OPENGL
+ if (real_screen->format->Bshift > real_screen->format->Rshift) {
+ bgr = 1;
+ } else {
+ bgr = 0;
}
-
- ds->width = w;
- ds->height = h;
- if (!ds->shared_buf) {
- ds->depth = screen->format->BitsPerPixel;
- if (screen->format->Bshift > screen->format->Rshift) {
- bgr = 1;
- } else {
- bgr = 0;
- }
- shared = NULL;
- ds->data = screen->pixels;
- ds->linesize = screen->pitch;
- } else {
- ds->linesize = linesize;
-#ifdef CONFIG_OPENGL
- switch(screen->format->BitsPerPixel) {
+ switch(real_screen->format->BitsPerPixel) {
case 8:
gl_format = GL_RGB;
break;
@@ -297,36 +217,15 @@
gl_format = GL_RGB;
break;
case 32:
- if (!screen->format->Rshift)
+ if (!real_screen->format->Rshift)
gl_format = GL_BGRA;
else
gl_format = GL_RGBA;
break;
- };
+ };
#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_get_bytes_per_pixel(ds), 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;
-#ifdef CONFIG_OPENGL
- if (opengl_enabled) {
- ds->dpy_update = opengl_update;
- }
-#endif
+ dcl->dpy_setdata(ds);
}
/* generic keyboard conversion */
@@ -525,8 +424,8 @@
}
SDL_GetMouseState(&dx, &dy);
- dx = dx * 0x7FFF / (screen->w - 1);
- dy = dy * 0x7FFF / (screen->h - 1);
+ dx = dx * 0x7FFF / (real_screen->w - 1);
+ dy = dy * 0x7FFF / (real_screen->h - 1);
} else if (absolute_enabled) {
sdl_show_cursor();
absolute_enabled = 0;
@@ -538,7 +437,7 @@
static void toggle_full_screen(DisplayState *ds)
{
gui_fullscreen = !gui_fullscreen;
- sdl_resize_shared(ds, ds_get_width(ds), ds_get_height(ds),
ds_get_bits_per_pixel(ds), ds_get_linesize(ds), ds_get_data(ds));
+ sdl_resize(ds);
if (gui_fullscreen) {
gui_saved_grab = gui_grab;
sdl_grab_start();
@@ -566,7 +465,7 @@
while (SDL_PollEvent(ev)) {
switch (ev->type) {
case SDL_VIDEOEXPOSE:
- ds->dpy_update(ds, 0, 0, ds->width, ds->height);
+ dcl->dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
@@ -726,23 +625,23 @@
if (ev->active.state & SDL_APPACTIVE) {
if (ev->active.gain) {
/* Back to default interval */
- ds->gui_timer_interval = 0;
- ds->idle = 0;
+ dcl->gui_timer_interval = 0;
+ dcl->idle = 0;
} else {
/* Sleeping interval */
- ds->gui_timer_interval = 500;
- ds->idle = 1;
+ dcl->gui_timer_interval = 500;
+ dcl->idle = 1;
}
}
break;
#ifdef CONFIG_OPENGL
case SDL_VIDEORESIZE:
{
- if (ds->shared_buf && opengl_enabled) {
+ if (opengl_enabled) {
SDL_ResizeEvent *rev = &ev->resize;
- screen = SDL_SetVideoMode(rev->w, rev->h, 0,
SDL_OPENGL|SDL_RESIZABLE);
- opengl_setdata(ds, ds->data);
- opengl_update(ds, 0, 0, ds->width, ds->height);
+ real_screen = SDL_SetVideoMode(rev->w, rev->h, 0,
SDL_OPENGL|SDL_RESIZABLE);
+ opengl_setdata(ds);
+ opengl_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
}
break;
}
@@ -792,17 +691,21 @@
signal(SIGQUIT, SIG_DFL);
#endif
- ds->dpy_update = sdl_update;
- ds->dpy_resize = sdl_resize;
- ds->dpy_resize_shared = sdl_resize_shared;
- ds->dpy_refresh = sdl_refresh;
- ds->dpy_setdata = sdl_setdata;
+ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+ if (!dcl)
+ exit(1);
+ dcl->dpy_update = sdl_update;
+ dcl->dpy_resize = sdl_resize;
+ dcl->dpy_refresh = sdl_refresh;
+ dcl->dpy_setdata = sdl_setdata;
#ifdef CONFIG_OPENGL
- if (opengl_enabled)
- ds->dpy_setdata = opengl_setdata;
+ if (opengl_enabled) {
+ dcl->dpy_update = opengl_update;
+ dcl->dpy_setdata = opengl_setdata;
+ }
#endif
+ register_displaychangelistener(ds, dcl);
- sdl_resize(ds, 640, 400);
sdl_update_caption();
SDL_EnableKeyRepeat(250, 50);
gui_grab = 0;
diff --git a/vl.c b/vl.c
--- a/vl.c
+++ b/vl.c
@@ -195,6 +195,7 @@
static DisplayState display_state;
int nographic;
static int curses;
+static int sdl;
const char* keyboard_layout = NULL;
int64_t ticks_per_sec;
ram_addr_t ram_size;
@@ -6245,7 +6246,7 @@
{
}
-static void dumb_resize(DisplayState *ds, int w, int h)
+static void dumb_resize(DisplayState *ds)
{
}
@@ -6258,14 +6259,15 @@
static void dumb_display_init(DisplayState *ds)
{
- ds->data = NULL;
- ds->linesize = 0;
- ds->depth = 0;
- ds->dpy_update = dumb_update;
- ds->dpy_resize = dumb_resize;
- ds->dpy_refresh = dumb_refresh;
- ds->gui_timer_interval = 500;
- ds->idle = 1;
+ DisplayChangeListener *dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+ if (!dcl)
+ exit(1);
+ dcl->dpy_update = dumb_update;
+ dcl->dpy_resize = dumb_resize;
+ dcl->dpy_refresh = NULL;
+ dcl->idle = 1;
+ dcl->gui_timer_interval = 500;
+ register_displaychangelistener(ds, dcl);
}
/***********************************************************/
@@ -7901,13 +7903,19 @@
static void gui_update(void *opaque)
{
+ uint64_t interval = GUI_REFRESH_INTERVAL;
DisplayState *ds = opaque;
- ds->dpy_refresh(ds);
- qemu_mod_timer(ds->gui_timer,
- (ds->gui_timer_interval ?
- ds->gui_timer_interval :
- GUI_REFRESH_INTERVAL)
- + qemu_get_clock(rt_clock));
+ DisplayChangeListener *dcl = ds->listeners;
+
+ dpy_refresh(ds);
+
+ while (dcl != NULL) {
+ if (dcl->gui_timer_interval &&
+ dcl->gui_timer_interval < interval)
+ interval = dcl->gui_timer_interval;
+ dcl = dcl->next;
+ }
+ qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
}
struct vm_change_state_entry {
@@ -8394,6 +8402,7 @@
"-no-frame open SDL window without a frame and window
decorations\n"
"-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of
Ctrl-Alt)\n"
"-no-quit disable SDL window close capability\n"
+ "-sdl enable SDL\n"
#endif
#ifdef CONFIG_OPENGL
"-disable-opengl disable OpenGL rendering, using SDL"
@@ -8607,6 +8616,7 @@
QEMU_OPTION_no_frame,
QEMU_OPTION_alt_grab,
QEMU_OPTION_no_quit,
+ QEMU_OPTION_sdl,
QEMU_OPTION_domid,
QEMU_OPTION_disable_opengl,
QEMU_OPTION_direct_pci,
@@ -8727,6 +8737,7 @@
{ "no-frame", 0, QEMU_OPTION_no_frame },
{ "alt-grab", 0, QEMU_OPTION_alt_grab },
{ "no-quit", 0, QEMU_OPTION_no_quit },
+ { "sdl", 0, QEMU_OPTION_sdl },
#endif
#ifdef CONFIG_OPENGL
{ "disable-opengl", 0, QEMU_OPTION_disable_opengl },
@@ -9048,6 +9059,7 @@
const char *kernel_filename, *kernel_cmdline;
const char *boot_devices = "";
DisplayState *ds = &display_state;
+ DisplayChangeListener *dcl;
int cyls, heads, secs, translation;
const char *net_clients[MAX_NET_CLIENTS];
int nb_net_clients;
@@ -9593,6 +9605,9 @@
break;
case QEMU_OPTION_no_quit:
no_quit = 1;
+ break;
+ case QEMU_OPTION_sdl:
+ sdl = 1;
break;
#endif
case QEMU_OPTION_disable_opengl:
@@ -10033,6 +10048,7 @@
/* terminal init */
memset(&display_state, 0, sizeof(display_state));
+ ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
#ifdef CONFIG_STUBDOM
if (xenfb_pv_display_init(ds) == 0) {
} else
@@ -10042,33 +10058,35 @@
fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
exit(1);
}
- /* nearly nothing to do */
- dumb_display_init(ds);
- } else 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);
- } else
+ } else {
#if defined(CONFIG_CURSES)
- if (curses) {
- curses_display_init(ds, full_screen);
- } else
-#endif
- {
+ if (curses) {
+ /* At the moment curses cannot be used with other displays */
+ 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 defined(CONFIG_SDL)
- 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)
- cocoa_display_init(ds, full_screen);
-#else
- dumb_display_init(ds);
-#endif
- }
+ if (sdl || !vnc_display)
+ cocoa_display_init(ds, full_screen);
+#endif
+ }
+ }
+ dpy_resize(ds);
#ifndef _WIN32
/* must be after terminal init, SDL library changes signal handlers */
@@ -10155,9 +10173,13 @@
}
}
- if (display_state.dpy_refresh) {
- display_state.gui_timer = qemu_new_timer(rt_clock, gui_update,
&display_state);
- qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
+ dcl = ds->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_refresh != NULL) {
+ display_state.gui_timer = qemu_new_timer(rt_clock, gui_update,
&display_state);
+ qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
+ }
+ dcl = dcl->next;
}
#ifdef CONFIG_GDBSTUB
diff --git a/vnc.c b/vnc.c
--- a/vnc.c
+++ b/vnc.c
@@ -232,6 +232,7 @@
};
static VncState *vnc_state; /* needed for info vnc */
+static DisplayChangeListener *dcl;
#define DIRTY_PIXEL_BITS 64
#define X2DP_DOWN(vs, x) ((x) >> (vs)->dirty_pixel_shift)
@@ -277,7 +278,7 @@
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);
+static void vnc_colordepth(DisplayState *ds);
#if 0
static inline void vnc_set_bit(uint32_t *d, int k)
@@ -340,8 +341,8 @@
mask = ~(0ULL);
h += y;
- if (h > vs->ds->height)
- h = vs->ds->height;
+ if (h > ds_get_height(vs->ds))
+ h = ds_get_height(vs->ds);
for (; y < h; y++)
row[y] |= mask;
}
@@ -369,69 +370,43 @@
vnc_write_s32(vs, encoding);
}
-static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth,
int linesize, void *pixels)
+static void vnc_dpy_resize(DisplayState *ds)
{
- 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)
- ds->data = qemu_realloc(ds->data, h * ds->linesize);
- else
- ds->data = malloc(h * ds->linesize);
- allocated = 1;
- } else {
- ds->linesize = linesize;
- if (allocated) {
- free(ds->data);
- allocated = 0;
- }
- }
- vs->old_data = qemu_realloc(vs->old_data, h * ds->linesize);
- vs->dirty_row = qemu_realloc(vs->dirty_row, h * sizeof(vs->dirty_row[0]));
- vs->update_row = qemu_realloc(vs->update_row, h *
sizeof(vs->dirty_row[0]));
+ vs->old_data = qemu_realloc(vs->old_data, ds_get_height(ds) *
ds_get_linesize(ds));
+ vs->dirty_row = qemu_realloc(vs->dirty_row, ds_get_height(ds) *
sizeof(vs->dirty_row[0]));
+ vs->update_row = qemu_realloc(vs->update_row, ds_get_height(ds) *
sizeof(vs->dirty_row[0]));
- if (ds->data == NULL || vs->old_data == NULL ||
- vs->dirty_row == NULL || vs->update_row == NULL) {
+ if (vs->old_data == NULL || vs->dirty_row == NULL || vs->update_row ==
NULL) {
fprintf(stderr, "vnc: memory allocation failed\n");
exit(1);
}
- if (ds->depth != vs->depth * 8) {
- ds->depth = vs->depth * 8;
+ if (ds_get_bytes_per_pixel(ds) != vs->depth)
console_color_init(ds);
- }
- size_changed = ds->width != w || ds->height != h;
- ds->width = w;
- ds->height = h;
+ vnc_colordepth(ds);
+ size_changed = ds_get_width(ds) != vs->width || ds_get_height(ds) !=
vs->height;
if (vs->csock != -1 && vs->has_resize && size_changed) {
- vs->width = ds->width;
- vs->height = ds->height;
+ vs->width = ds_get_width(ds);
+ vs->height = ds_get_height(ds);
if (vs->update_requested) {
vnc_write_u8(vs, 0); /* msg id */
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
+ vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds),
ds_get_height(ds), -223);
vnc_flush(vs);
vs->update_requested--;
} else {
- enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
+ enqueue_framebuffer_update(vs, 0, 0, ds_get_width(ds),
ds_get_height(ds), -223);
}
}
vs->dirty_pixel_shift = 0;
- for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
+ for (o = DIRTY_PIXEL_BITS; o < ds_get_width(ds); 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);
+ framebuffer_set_updated(vs, 0, 0, ds_get_width(ds), ds_get_height(ds));
}
/* fastest code */
@@ -589,19 +564,8 @@
static void vnc_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
dst_y, int w, int h)
{
- int src, dst;
- uint8_t *src_row;
- uint8_t *dst_row;
- uint8_t *old_row;
- int y = 0;
- int pitch = ds_get_linesize(ds);
VncState *vs = ds->opaque;
int updating_client = 1;
-
- if (ds->shared_buf) {
- framebuffer_set_updated(vs, dst_x, dst_y, w, h);
- return;
- }
if (!vs->update_requested ||
src_x < vs->visible_x || src_y < vs->visible_y ||
@@ -613,27 +577,7 @@
updating_client = 0;
if (updating_client)
- _vnc_update_client(vs);
-
- if (dst_y > src_y) {
- y = h - 1;
- pitch = -pitch;
- }
-
- src = (ds_get_linesize(ds) * (src_y + y) + vs->depth * src_x);
- dst = (ds_get_linesize(ds) * (dst_y + y) + vs->depth * dst_x);
-
- src_row = ds_get_data(ds) + src;
- dst_row = ds_get_data(ds) + dst;
- old_row = vs->old_data + dst;
-
- for (y = 0; y < h; y++) {
- memmove(old_row, src_row, w * vs->depth);
- memmove(dst_row, src_row, w * vs->depth);
- src_row += pitch;
- dst_row += pitch;
- old_row += pitch;
- }
+ _vnc_update_client(vs);
if (updating_client && vs->csock != -1 && !vs->has_update) {
vnc_write_u8(vs, 0); /* msg id */
@@ -695,16 +639,16 @@
now = qemu_get_clock(rt_clock);
if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
- width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
+ width_mask = (1ULL << X2DP_UP(vs, ds_get_width(vs->ds))) - 1;
else
width_mask = ~(0ULL);
/* Walk through the dirty map and eliminate tiles that really
aren't dirty */
- row = vs->ds->data;
+ row = ds_get_data(vs->ds);
old_row = vs->old_data;
- for (y = 0; y < vs->ds->height; y++) {
+ for (y = 0; y < ds_get_height(vs->ds); y++) {
if (vs->dirty_row[y] & width_mask) {
int x;
uint8_t *ptr, *old_ptr;
@@ -712,7 +656,7 @@
ptr = row;
old_ptr = old_row;
- for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
+ for (x = 0; x < X2DP_UP(vs, ds_get_width(vs->ds)); x++) {
if (vs->dirty_row[y] & (1ULL << x)) {
if (memcmp(old_ptr, ptr, tile_bytes)) {
vs->has_update = 1;
@@ -727,12 +671,12 @@
}
}
- row += vs->ds->linesize;
- old_row += vs->ds->linesize;
+ row += ds_get_linesize(vs->ds);
+ old_row += ds_get_linesize(vs->ds);
}
- if (!vs->has_update || vs->visible_y >= vs->ds->height ||
- vs->visible_x >= vs->ds->width)
+ if (!vs->has_update || vs->visible_y >= ds_get_height(vs->ds) ||
+ vs->visible_x >= ds_get_width(vs->ds))
goto backoff;
/* Count rectangles */
@@ -743,11 +687,11 @@
vnc_write_u16(vs, 0);
maxy = vs->visible_y + vs->visible_h;
- if (maxy > vs->ds->height)
- maxy = vs->ds->height;
+ if (maxy > ds_get_height(vs->ds))
+ maxy = ds_get_height(vs->ds);
maxx = vs->visible_x + vs->visible_w;
- if (maxx > vs->ds->width)
- maxx = vs->ds->width;
+ if (maxx > ds_get_width(vs->ds))
+ maxx = ds_get_width(vs->ds);
for (y = vs->visible_y; y < maxy; y++) {
int x;
@@ -791,7 +735,7 @@
vs->has_update = 0;
vnc_flush(vs);
vs->last_update_time = now;
- vs->ds->idle = 0;
+ dcl->idle = 0;
vs->timer_interval /= 2;
if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
@@ -806,7 +750,7 @@
vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
if (!vs->update_requested) {
- vs->ds->idle = 1;
+ dcl->idle = 1;
} else {
/* Send a null update. If the client is no longer
interested (e.g. minimised) it'll ignore this, and we
@@ -992,7 +936,7 @@
qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL);
closesocket(vs->csock);
vs->csock = -1;
- vs->ds->idle = 1;
+ dcl->idle = 1;
buffer_reset(&vs->input);
buffer_reset(&vs->output);
free_queue(vs);
@@ -1213,12 +1157,12 @@
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
vnc_framebuffer_update(vs, absolute, 0,
- vs->ds->width, vs->ds->height, -257);
+ ds_get_width(vs->ds), ds_get_height(vs->ds),
-257);
vnc_flush(vs);
vs->update_requested--;
} else {
enqueue_framebuffer_update(vs, absolute, 0,
- vs->ds->width, vs->ds->height, -257);
+ ds_get_width(vs->ds), ds_get_height(vs->ds),
-257);
}
}
vs->absolute = absolute;
@@ -1241,8 +1185,8 @@
dz = 1;
if (vs->absolute) {
- kbd_mouse_event(x * 0x7FFF / (vs->ds->width - 1),
- y * 0x7FFF / (vs->ds->height - 1),
+ kbd_mouse_event(x * 0x7FFF / (ds_get_width(vs->ds) - 1),
+ y * 0x7FFF / (ds_get_height(vs->ds) - 1),
dz, buttons);
} else if (vs->has_pointer_type_change) {
x -= 0x7FFF;
@@ -1568,7 +1512,7 @@
vs->has_pointer_type_change = 0;
vs->has_WMVi = 0;
vs->absolute = -1;
- vs->ds->dpy_copy = NULL;
+ dcl->dpy_copy = NULL;
for (i = n_encodings - 1; i >= 0; i--) {
switch (encodings[i]) {
@@ -1576,7 +1520,7 @@
vs->has_hextile = 0;
break;
case 1: /* CopyRect */
- vs->ds->dpy_copy = vnc_copy;
+ dcl->dpy_copy = vnc_copy;
break;
case 5: /* Hextile */
vs->has_hextile = 1;
@@ -1717,30 +1661,15 @@
vnc_write(vs, pad, 3); /* padding */
}
-static void vnc_dpy_setdata(DisplayState *ds, void *pixels)
+static void vnc_dpy_setdata(DisplayState *ds)
{
- ds->data = pixels;
+ /* We don't have to do anything */
}
-static void vnc_colourdepth(DisplayState *ds, int depth)
+static void vnc_colordepth(DisplayState *ds)
{
int host_big_endian_flag;
struct VncState *vs = ds->opaque;
-
- switch (depth) {
- case 24:
- ds->shared_buf = 0;
- if (ds->depth == 32) return;
- depth = 32;
- break;
- case 8:
- case 0:
- ds->shared_buf = 0;
- return;
- default:
- ds->shared_buf = 1;
- break;
- }
#ifdef WORDS_BIGENDIAN
host_big_endian_flag = 1;
@@ -1748,9 +1677,9 @@
host_big_endian_flag = 0;
#endif
- switch (depth) {
+ switch (ds_get_bits_per_pixel(ds)) {
case 8:
- vs->depth = depth / 8;
+ vs->depth = 1;
vs->red_max1 = 7;
vs->green_max1 = 7;
vs->blue_max1 = 3;
@@ -1759,7 +1688,7 @@
vs->blue_shift1 = 0;
break;
case 16:
- vs->depth = depth / 8;
+ vs->depth = 2;
vs->red_max1 = 31;
vs->green_max1 = 63;
vs->blue_max1 = 31;
@@ -1787,12 +1716,12 @@
vnc_write_u8(vs, 0); /* msg id */
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height,
0x574D5669);
+ vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds),
ds_get_height(ds), 0x574D5669);
pixel_format_message(vs);
vnc_flush(vs);
vs->update_requested--;
} else {
- enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height,
0x574D5669);
+ enqueue_framebuffer_update(vs, 0, 0, ds_get_width(ds),
ds_get_height(ds), 0x574D5669);
}
} else {
if (vs->pix_bpp == 4 && vs->depth == 4 &&
@@ -2536,17 +2465,17 @@
vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
if (vs->csock != -1) {
VNC_DEBUG("New client on socket %d\n", vs->csock);
- vs->ds->idle = 0;
+ dcl->idle = 0;
socket_set_nonblock(vs->csock);
qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);
vnc_write(vs, "RFB 003.008\n", 12);
vnc_flush(vs);
vnc_read_when(vs, protocol_version, 12);
- framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
+ framebuffer_set_updated(vs, 0, 0, ds_get_width(vs->ds),
ds_get_height(vs->ds));
vs->has_resize = 0;
vs->has_hextile = 0;
vs->update_requested = 0;
- vs->ds->dpy_copy = NULL;
+ dcl->dpy_copy = NULL;
vnc_timer_init(vs);
}
}
@@ -2558,11 +2487,12 @@
VncState *vs;
vs = qemu_mallocz(sizeof(VncState));
- if (!vs)
+ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+ if (!vs || !dcl)
exit(1);
ds->opaque = vs;
- ds->idle = 1;
+ dcl->idle = 1;
vnc_state = vs;
vs->display = NULL;
vs->password = NULL;
@@ -2582,17 +2512,11 @@
exit(1);
vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
- vs->ds->data = NULL;
- vs->ds->dpy_update = vnc_dpy_update;
- vs->ds->dpy_resize = vnc_dpy_resize;
- 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_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
+ dcl->dpy_update = vnc_dpy_update;
+ dcl->dpy_resize = vnc_dpy_resize;
+ dcl->dpy_setdata = vnc_dpy_setdata;
+ dcl->dpy_refresh = NULL;
+ register_displaychangelistener(ds, dcl);
}
#ifdef CONFIG_VNC_TLS
diff --git a/xenfbfront.c b/xenfbfront.c
--- a/xenfbfront.c
+++ b/xenfbfront.c
@@ -23,6 +23,7 @@
static char *kbd_path, *fb_path;
static unsigned char linux2scancode[KEY_MAX + 1];
+static DisplayChangeListener *dcl;
extern uint32_t vga_ram_size;
@@ -47,50 +48,27 @@
fbfront_update(fb_dev, x, y, w, h);
}
-static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth,
int linesize, void *pixels)
+static void xenfb_pv_resize(DisplayState *ds)
{
XenFBState *xs = ds->opaque;
struct fbfront_dev *fb_dev = xs->fb_dev;
int offset;
- fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
- ds->width = w;
- ds->height = h;
- if (!depth) {
- ds->shared_buf = 0;
- ds->depth = 32;
- } else {
- ds->shared_buf = 1;
- ds->depth = depth;
- }
- if (!linesize)
- ds->shared_buf = 0;
- if (!ds->shared_buf)
- linesize = w * 4;
- ds->linesize = linesize;
+ fprintf(stderr,"resize to %dx%d@%d, %d required\n", ds_get_width(ds),
ds_get_height(ds), ds_get_bits_per_pixel(ds), ds_get_linesize(ds));
if (!fb_dev)
return;
- if (ds->shared_buf) {
- offset = pixels - xs->vga_vram;
- ds->data = pixels;
- fbfront_resize(fb_dev, ds_get_width(ds), ds_get_height(ds),
ds_get_linesize(ds), ds_get_bits_per_pixel(ds), offset);
- } else {
- ds->data = xs->nonshared_vram;
- fbfront_resize(fb_dev, w, h, linesize, ds_get_bits_per_pixel(ds),
vga_ram_size);
- }
+ if (!(ds->surface->flags & QEMU_ALLOCATED_FLAG))
+ offset = ((void *) ds_get_data(ds)) - xs->vga_vram;
+ else
+ offset = vga_ram_size;
+ fbfront_resize(fb_dev, ds_get_width(ds), ds_get_height(ds),
ds_get_linesize(ds), ds_get_bits_per_pixel(ds), offset);
}
-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_setdata(DisplayState *ds, void *pixels)
+static void xenfb_pv_setdata(DisplayState *ds)
{
XenFBState *xs = ds->opaque;
struct fbfront_dev *fb_dev = xs->fb_dev;
- int offset = pixels - xs->vga_vram;
- ds->data = pixels;
+ int offset = ((void *) ds_get_data(ds)) - xs->vga_vram;
if (!fb_dev)
return;
fbfront_resize(fb_dev, ds_get_width(ds), ds_get_height(ds),
ds_get_linesize(ds), ds_get_bits_per_pixel(ds), offset);
@@ -115,12 +93,12 @@
case XENFB_TYPE_REFRESH_PERIOD:
if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
/* Sleeping interval */
- ds->idle = 1;
- ds->gui_timer_interval = 500;
+ dcl->idle = 1;
+ dcl->gui_timer_interval = 500;
} else {
/* Set interval */
- ds->idle = 0;
- ds->gui_timer_interval = buf[i].refresh_period.period;
+ dcl->idle = 0;
+ dcl->gui_timer_interval = buf[i].refresh_period.period;
}
default:
/* ignore unknown events */
@@ -247,22 +225,19 @@
init_SEMAPHORE(&xs->kbd_sem, 0);
xs->ds = ds;
+ xs->nonshared_vram = ds_get_data(ds);
create_thread("kbdfront", kbdfront_thread, (void*) xs);
- ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, vga_ram_size);
- memset(ds->data, 0, vga_ram_size);
+ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+ if (!dcl)
+ exit(1);
ds->opaque = xs;
- ds->depth = 32;
- ds->bgr = 0;
- ds->width = 640;
- ds->height = 400;
- ds->linesize = 640 * 4;
- ds->dpy_update = xenfb_pv_update;
- ds->dpy_resize = xenfb_pv_resize;
- ds->dpy_resize_shared = xenfb_pv_resize_shared;
- ds->dpy_setdata = xenfb_pv_setdata;
- ds->dpy_refresh = xenfb_pv_refresh;
+ dcl->dpy_update = xenfb_pv_update;
+ dcl->dpy_resize = xenfb_pv_resize;
+ dcl->dpy_setdata = xenfb_pv_setdata;
+ dcl->dpy_refresh = xenfb_pv_refresh;
+ register_displaychangelistener(ds, dcl);
return 0;
}
@@ -295,11 +270,10 @@
}
free(fb_path);
- if (ds->shared_buf) {
- offset = (void*) ds->data - xs->vga_vram;
+ if (!(ds->surface->flags & QEMU_ALLOCATED_FLAG)) {
+ offset = (void*) ds_get_data(ds) - xs->vga_vram;
} else {
offset = vga_ram_size;
- ds->data = xs->nonshared_vram;
}
if (offset)
fbfront_resize(fb_dev, ds_get_width(ds), ds_get_height(ds),
ds_get_linesize(ds), ds_get_bits_per_pixel(ds), offset);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|