* [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures.
@ 2013-03-01 9:00 Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 01/12] console: fix displaychangelisteners interface Gerd Hoffmann
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hi,
This patch series continues the console & display code cleanups.
It's RfC because it is (a) not complete yet and (b) most likely
breaks the build (xen, cocoa). If someone wants help fill the
gaps (especially cocoa) patches are very welcome.
The short-team goal I'm heading to is to make the DisplaySurface
(and *only* the DisplaySurface) the central data structure for
the display renderers in ui/. They get one, they render it, they
are notified about updates, they are notified when the surface
changes. Done, there is nothing else they need to know or care
about.
The longer-term goal building on top of this is to put the console
internals upside down (without having to touch the ui renderers in
the process). I want have one DisplaySurface per console, which then
lives forever, and console switches (Ctrl-Alt-$number in vnc+sdl)
become a simple surface switch. Alternative ways to handle consoles
becomes alot easier to implement, in gtk we can probably simply put
each DisplaySurface into one tab. The need to ask the vga emulation
to redraw the screen on console switches goes away, vga_hw_invalidate
can be zapped. We can stop hopping through loops for screendumps,
we can just write out the DisplaySurface content.
Oh, and this also paves the way to handle multihead in a reasonable
way.
cheers,
Gerd
Gerd Hoffmann (12):
console: fix displaychangelisteners interface
console: kill DisplayState->opaque
spice: zap sdpy global
qxl: zap qxl0 global
qxl: better vga init in enter_vga_mode
sdl: drop dead code
console: rework DisplaySurface handling [vga emu side]
console: rework DisplaySurface handling [dcl/ui side]
console: add surface_*() getters
gtk: stop using DisplayState
vnc: stop using DisplayState
sdl: stop using DisplayState
hw/nseries.c | 7 --
hw/palm.c | 7 --
hw/qxl-render.c | 12 +--
hw/qxl.c | 51 ++++++----
hw/vga.c | 17 ++--
include/ui/console.h | 226 +++++++++++++++-----------------------------
include/ui/spice-display.h | 4 +-
trace-events | 7 +-
ui/cocoa.m | 26 +++--
ui/console.c | 193 +++++++++++++++++++++++++++++++------
ui/curses.c | 32 +++++--
ui/gtk.c | 162 ++++++++++++++++++-------------
ui/sdl.c | 123 ++++++++++++++----------
ui/spice-display.c | 51 ++++++----
ui/vnc-enc-tight.c | 7 +-
ui/vnc-jobs.c | 1 -
ui/vnc.c | 144 +++++++++++++++-------------
ui/vnc.h | 4 +-
vl.c | 6 +-
19 files changed, 611 insertions(+), 469 deletions(-)
--
1.7.9.7
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 01/12] console: fix displaychangelisteners interface
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 02/12] console: kill DisplayState->opaque Gerd Hoffmann
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Andreas Färber, Gerd Hoffmann, Anthony Liguori
Split callbacks into separate Ops struct. Pass DisplayChangeListener
pointer as first argument to all callbacks. Uninline a bunch of
display functions and move them from console.h to console.c
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qxl.c | 18 ++--
include/ui/console.h | 207 ++++++++++++--------------------------------
include/ui/spice-display.h | 1 +
trace-events | 2 +
ui/cocoa.m | 26 ++++--
ui/console.c | 144 ++++++++++++++++++++++++++++++
ui/curses.c | 32 ++++---
ui/gtk.c | 30 ++++---
ui/sdl.c | 44 ++++++----
ui/spice-display.c | 19 ++--
ui/vnc.c | 44 +++++++---
vl.c | 6 +-
12 files changed, 345 insertions(+), 228 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index 2e1c5e2..cb3d317 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1866,21 +1866,25 @@ static void qxl_vm_change_state_handler(void *opaque, int running,
/* display change listener */
-static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
+static void display_update(DisplayChangeListener *dcl,
+ struct DisplayState *ds,
+ int x, int y, int w, int h)
{
if (qxl0->mode == QXL_MODE_VGA) {
qemu_spice_display_update(&qxl0->ssd, x, y, w, h);
}
}
-static void display_resize(struct DisplayState *ds)
+static void display_resize(DisplayChangeListener *dcl,
+ struct DisplayState *ds)
{
if (qxl0->mode == QXL_MODE_VGA) {
qemu_spice_display_resize(&qxl0->ssd);
}
}
-static void display_refresh(struct DisplayState *ds)
+static void display_refresh(DisplayChangeListener *dcl,
+ struct DisplayState *ds)
{
if (qxl0->mode == QXL_MODE_VGA) {
qemu_spice_display_refresh(&qxl0->ssd);
@@ -1891,10 +1895,11 @@ static void display_refresh(struct DisplayState *ds)
}
}
-static DisplayChangeListener display_listener = {
+static DisplayChangeListenerOps display_listener_ops = {
+ .dpy_name = "spice/qxl",
.dpy_gfx_update = display_update,
.dpy_gfx_resize = display_resize,
- .dpy_refresh = display_refresh,
+ .dpy_refresh = display_refresh,
};
static void qxl_init_ramsize(PCIQXLDevice *qxl)
@@ -2076,7 +2081,8 @@ static int qxl_init_primary(PCIDevice *dev)
return rc;
}
- register_displaychangelistener(vga->ds, &display_listener);
+ qxl->ssd.dcl.ops = &display_listener_ops;
+ register_displaychangelistener(vga->ds, &qxl->ssd.dcl);
return rc;
}
diff --git a/include/ui/console.h b/include/ui/console.h
index c42bca6..695eabb 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -147,24 +147,46 @@ void cursor_set_mono(QEMUCursor *c,
void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
-struct DisplayChangeListener {
- int idle;
- uint64_t gui_timer_interval;
-
- void (*dpy_refresh)(struct DisplayState *s);
-
- void (*dpy_gfx_update)(struct DisplayState *s, int x, int y, int w, int h);
- void (*dpy_gfx_resize)(struct DisplayState *s);
- void (*dpy_gfx_setdata)(struct DisplayState *s);
- void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
+typedef struct DisplayChangeListenerOps {
+ const char *dpy_name;
+
+ void (*dpy_refresh)(DisplayChangeListener *dcl,
+ struct DisplayState *s);
+
+ void (*dpy_gfx_update)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ int x, int y, int w, int h);
+ void (*dpy_gfx_resize)(DisplayChangeListener *dcl,
+ struct DisplayState *s);
+ void (*dpy_gfx_setdata)(DisplayChangeListener *dcl,
+ struct DisplayState *s);
+ void (*dpy_gfx_copy)(DisplayChangeListener *dcl,
+ struct DisplayState *s, int src_x, int src_y,
int dst_x, int dst_y, int w, int h);
- void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
- void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
- void (*dpy_text_update)(struct DisplayState *s, int x, int y, int w, int h);
+ void (*dpy_text_cursor)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ int x, int y);
+ void (*dpy_text_resize)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ int w, int h);
+ void (*dpy_text_update)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ int x, int y, int w, int h);
+
+ void (*dpy_mouse_set)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ int x, int y, int on);
+ void (*dpy_cursor_define)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ QEMUCursor *cursor);
+} DisplayChangeListenerOps;
- void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
- void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
+struct DisplayChangeListener {
+ int idle;
+ uint64_t gui_timer_interval;
+ const DisplayChangeListenerOps *ops;
+ DisplayState *ds;
QLIST_ENTRY(DisplayChangeListener) next;
};
@@ -210,145 +232,22 @@ static inline int is_buffer_shared(DisplaySurface *surface)
void gui_setup_refresh(DisplayState *ds);
-static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
-{
- QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
- gui_setup_refresh(ds);
- if (dcl->dpy_gfx_resize) {
- dcl->dpy_gfx_resize(ds);
- }
-}
-
-static inline void unregister_displaychangelistener(DisplayState *ds,
- DisplayChangeListener *dcl)
-{
- QLIST_REMOVE(dcl, next);
- gui_setup_refresh(ds);
-}
-
-static inline void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
-{
- struct DisplayChangeListener *dcl;
- int width = pixman_image_get_width(s->surface->image);
- int height = pixman_image_get_height(s->surface->image);
-
- x = MAX(x, 0);
- y = MAX(y, 0);
- x = MIN(x, width);
- y = MIN(y, height);
- w = MIN(w, width - x);
- h = MIN(h, height - y);
-
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_gfx_update) {
- dcl->dpy_gfx_update(s, x, y, w, h);
- }
- }
-}
-
-static inline void dpy_gfx_resize(DisplayState *s)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_gfx_resize) {
- dcl->dpy_gfx_resize(s);
- }
- }
-}
-
-static inline void dpy_gfx_setdata(DisplayState *s)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_gfx_setdata) {
- dcl->dpy_gfx_setdata(s);
- }
- }
-}
-
-static inline void dpy_refresh(DisplayState *s)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_refresh) {
- dcl->dpy_refresh(s);
- }
- }
-}
-
-static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
- int dst_x, int dst_y, int w, int h)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_gfx_copy) {
- dcl->dpy_gfx_copy(s, src_x, src_y, dst_x, dst_y, w, h);
- } else { /* TODO */
- dcl->dpy_gfx_update(s, dst_x, dst_y, w, h);
- }
- }
-}
-
-static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_text_cursor) {
- dcl->dpy_text_cursor(s, x, y);
- }
- }
-}
-
-static inline void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_text_update) {
- dcl->dpy_text_update(s, x, y, w, h);
- }
- }
-}
-
-static inline void dpy_text_resize(DisplayState *s, int w, int h)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_text_resize) {
- dcl->dpy_text_resize(s, w, h);
- }
- }
-}
-
-static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_mouse_set) {
- dcl->dpy_mouse_set(s, x, y, on);
- }
- }
-}
-
-static inline void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_cursor_define) {
- dcl->dpy_cursor_define(s, cursor);
- }
- }
-}
-
-static inline bool dpy_cursor_define_supported(struct DisplayState *s)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->dpy_cursor_define) {
- return true;
- }
- }
- return false;
-}
+void register_displaychangelistener(DisplayState *ds,
+ DisplayChangeListener *dcl);
+void unregister_displaychangelistener(DisplayChangeListener *dcl);
+
+void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h);
+void dpy_gfx_resize(DisplayState *s);
+void dpy_gfx_setdata(DisplayState *s);
+void dpy_refresh(DisplayState *s);
+void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
+ int dst_x, int dst_y, int w, int h);
+void dpy_text_cursor(struct DisplayState *s, int x, int y);
+void dpy_text_update(DisplayState *s, int x, int y, int w, int h);
+void dpy_text_resize(DisplayState *s, int w, int h);
+void dpy_mouse_set(struct DisplayState *s, int x, int y, int on);
+void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor);
+bool dpy_cursor_define_supported(struct DisplayState *s);
static inline int ds_get_linesize(DisplayState *ds)
{
diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index 46f9530..f2752aa 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -72,6 +72,7 @@ typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
struct SimpleSpiceDisplay {
DisplayState *ds;
+ DisplayChangeListener dcl;
void *buf;
int bufsize;
QXLWorker *worker;
diff --git a/trace-events b/trace-events
index a27ae43..984d7e3 100644
--- a/trace-events
+++ b/trace-events
@@ -958,6 +958,8 @@ dma_map_wait(void *dbs) "dbs=%p"
# console.h
displaysurface_free(void *display_state, void *display_surface) "state=%p surface=%p"
displaysurface_resize(void *display_state, void *display_surface, int width, int height) "state=%p surface=%p %dx%d"
+displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
+displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
# vga.c
ppm_save(const char *filename, void *display_surface) "%s surface=%p"
diff --git a/ui/cocoa.m b/ui/cocoa.m
index ca42413..b1fb30e 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -969,7 +969,9 @@ int main (int argc, const char * argv[]) {
#pragma mark qemu
-static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
+static void cocoa_update(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int x, int y, int w, int h)
{
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
@@ -986,14 +988,16 @@ static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
[cocoaView setNeedsDisplayInRect:rect];
}
-static void cocoa_resize(DisplayState *ds)
+static void cocoa_resize(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
COCOA_DEBUG("qemu_cocoa: cocoa_resize\n");
[cocoaView resizeContentToWidth:(int)(ds_get_width(ds)) height:(int)(ds_get_height(ds)) displayState:ds];
}
-static void cocoa_refresh(DisplayState *ds)
+static void cocoa_refresh(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
@@ -1030,6 +1034,14 @@ static void cocoa_cleanup(void)
g_free(dcl);
}
+static const DisplayChangeListenerOps dcl_ops = {
+ .dpy_name = "cocoa",
+ .dpy_gfx_update = cocoa_update;
+ .dpy_gfx_resize = cocoa_resize;
+ .dpy_gfx_setdata = cocoa_setdata;
+ .dpy_refresh = cocoa_refresh;
+};
+
void cocoa_display_init(DisplayState *ds, int full_screen)
{
COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
@@ -1037,12 +1049,8 @@ void cocoa_display_init(DisplayState *ds, int full_screen)
dcl = g_malloc0(sizeof(DisplayChangeListener));
// register vga output callbacks
- dcl->dpy_gfx_update = cocoa_update;
- dcl->dpy_gfx_resize = cocoa_resize;
- dcl->dpy_refresh = cocoa_refresh;
- dcl->dpy_gfx_setdata = cocoa_setdata;
-
- register_displaychangelistener(ds, dcl);
+ dcl->ops = &dcl_ops;
+ register_displaychangelistener(ds, dcl);
// register cleanup function
atexit(cocoa_cleanup);
diff --git a/ui/console.c b/ui/console.c
index 0d95f32..b0bc9e2 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1374,6 +1374,150 @@ void qemu_free_displaysurface(DisplayState *ds)
g_free(ds->surface);
}
+void register_displaychangelistener(DisplayState *ds,
+ DisplayChangeListener *dcl)
+{
+ trace_displaychangelistener_register(dcl, dcl->ops->dpy_name);
+ dcl->ds = ds;
+ QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
+ gui_setup_refresh(ds);
+ if (dcl->ops->dpy_gfx_resize) {
+ dcl->ops->dpy_gfx_resize(dcl, ds);
+ }
+}
+
+void unregister_displaychangelistener(DisplayChangeListener *dcl)
+{
+ DisplayState *ds = dcl->ds;
+ trace_displaychangelistener_unregister(dcl, dcl->ops->dpy_name);
+ QLIST_REMOVE(dcl, next);
+ gui_setup_refresh(ds);
+}
+
+void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
+{
+ struct DisplayChangeListener *dcl;
+ int width = pixman_image_get_width(s->surface->image);
+ int height = pixman_image_get_height(s->surface->image);
+
+ x = MAX(x, 0);
+ y = MAX(y, 0);
+ x = MIN(x, width);
+ y = MIN(y, height);
+ w = MIN(w, width - x);
+ h = MIN(h, height - y);
+
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_gfx_update) {
+ dcl->ops->dpy_gfx_update(dcl, s, x, y, w, h);
+ }
+ }
+}
+
+void dpy_gfx_resize(DisplayState *s)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_gfx_resize) {
+ dcl->ops->dpy_gfx_resize(dcl, s);
+ }
+ }
+}
+
+void dpy_gfx_setdata(DisplayState *s)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_gfx_setdata) {
+ dcl->ops->dpy_gfx_setdata(dcl, s);
+ }
+ }
+}
+
+void dpy_refresh(DisplayState *s)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_refresh) {
+ dcl->ops->dpy_refresh(dcl, s);
+ }
+ }
+}
+
+void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
+ int dst_x, int dst_y, int w, int h)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_gfx_copy) {
+ dcl->ops->dpy_gfx_copy(dcl, s, src_x, src_y, dst_x, dst_y, w, h);
+ } else { /* TODO */
+ dcl->ops->dpy_gfx_update(dcl, s, dst_x, dst_y, w, h);
+ }
+ }
+}
+
+void dpy_text_cursor(struct DisplayState *s, int x, int y)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_text_cursor) {
+ dcl->ops->dpy_text_cursor(dcl, s, x, y);
+ }
+ }
+}
+
+void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_text_update) {
+ dcl->ops->dpy_text_update(dcl, s, x, y, w, h);
+ }
+ }
+}
+
+void dpy_text_resize(DisplayState *s, int w, int h)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_text_resize) {
+ dcl->ops->dpy_text_resize(dcl, s, w, h);
+ }
+ }
+}
+
+void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_mouse_set) {
+ dcl->ops->dpy_mouse_set(dcl, s, x, y, on);
+ }
+ }
+}
+
+void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_cursor_define) {
+ dcl->ops->dpy_cursor_define(dcl, s, cursor);
+ }
+ }
+}
+
+bool dpy_cursor_define_supported(struct DisplayState *s)
+{
+ struct DisplayChangeListener *dcl;
+ QLIST_FOREACH(dcl, &s->listeners, next) {
+ if (dcl->ops->dpy_cursor_define) {
+ return true;
+ }
+ }
+ return false;
+}
+
static void dumb_display_init(void)
{
DisplayState *ds = g_malloc0(sizeof(DisplayState));
diff --git a/ui/curses.c b/ui/curses.c
index d78e378..ca9856c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -35,12 +35,15 @@
#define FONT_HEIGHT 16
#define FONT_WIDTH 8
+static DisplayChangeListener *dcl;
static console_ch_t screen[160 * 100];
static WINDOW *screenpad = NULL;
static int width, height, gwidth, gheight, invalidate;
static int px, py, sminx, sminy, smaxx, smaxy;
-static void curses_update(DisplayState *ds, int x, int y, int w, int h)
+static void curses_update(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int x, int y, int w, int h)
{
chtype *line;
@@ -91,7 +94,9 @@ static void curses_calc_pad(void)
}
}
-static void curses_resize(DisplayState *ds, int width, int height)
+static void curses_resize(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int width, int height)
{
if (width == gwidth && height == gheight) {
return;
@@ -128,7 +133,9 @@ static void curses_winch_handler(int signum)
#endif
#endif
-static void curses_cursor_position(DisplayState *ds, int x, int y)
+static void curses_cursor_position(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int x, int y)
{
if (x >= 0) {
x = sminx + x - px;
@@ -154,7 +161,8 @@ static void curses_cursor_position(DisplayState *ds, int x, int y)
static kbd_layout_t *kbd_layout = NULL;
-static void curses_refresh(DisplayState *ds)
+static void curses_refresh(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
int chr, nextchr, keysym, keycode, keycode_alt;
@@ -187,7 +195,7 @@ static void curses_refresh(DisplayState *ds)
clear();
refresh();
curses_calc_pad();
- curses_update(ds, 0, 0, width, height);
+ curses_update(dcl, ds, 0, 0, width, height);
continue;
}
#endif
@@ -323,9 +331,16 @@ static void curses_keyboard_setup(void)
}
}
+static const DisplayChangeListenerOps dcl_ops = {
+ .dpy_name = "curses",
+ .dpy_text_update = curses_update,
+ .dpy_text_resize = curses_resize,
+ .dpy_refresh = curses_refresh,
+ .dpy_text_cursor = curses_cursor_position,
+};
+
void curses_display_init(DisplayState *ds, int full_screen)
{
- DisplayChangeListener *dcl;
#ifndef _WIN32
if (!isatty(1)) {
fprintf(stderr, "We need a terminal output\n");
@@ -346,10 +361,7 @@ void curses_display_init(DisplayState *ds, int full_screen)
#endif
dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
- dcl->dpy_text_update = curses_update;
- dcl->dpy_text_resize = curses_resize;
- dcl->dpy_refresh = curses_refresh;
- dcl->dpy_text_cursor = curses_cursor_position;
+ dcl->ops = &dcl_ops;
register_displaychangelistener(ds, dcl);
invalidate = 1;
diff --git a/ui/gtk.c b/ui/gtk.c
index 544593e..e89d4b1 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -227,7 +227,8 @@ static void gd_update_caption(GtkDisplayState *s)
/** DisplayState Callbacks **/
-static void gd_update(DisplayState *ds, int x, int y, int w, int h)
+static void gd_update(DisplayChangeListener *dcl,
+ DisplayState *ds, int x, int y, int w, int h)
{
GtkDisplayState *s = ds->opaque;
int x1, x2, y1, y2;
@@ -259,12 +260,14 @@ static void gd_update(DisplayState *ds, int x, int y, int w, int h)
gtk_widget_queue_draw_area(s->drawing_area, mx + x1, my + y1, (x2 - x1), (y2 - y1));
}
-static void gd_refresh(DisplayState *ds)
+static void gd_refresh(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
vga_hw_update();
}
-static void gd_resize(DisplayState *ds)
+static void gd_resize(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
GtkDisplayState *s = ds->opaque;
cairo_format_t kind;
@@ -382,7 +385,7 @@ static gboolean gd_window_close(GtkWidget *widget, GdkEvent *event,
GtkDisplayState *s = opaque;
if (!no_quit) {
- unregister_displaychangelistener(s->ds, &s->dcl);
+ unregister_displaychangelistener(&s->dcl);
qmp_quit(NULL);
return FALSE;
}
@@ -735,7 +738,7 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
s->scale_x += .25;
s->scale_y += .25;
- gd_resize(s->ds);
+ gd_resize(&s->dcl, s->ds);
}
static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
@@ -751,7 +754,7 @@ static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
s->scale_x = MAX(s->scale_x, .25);
s->scale_y = MAX(s->scale_y, .25);
- gd_resize(s->ds);
+ gd_resize(&s->dcl, s->ds);
}
static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
@@ -761,7 +764,7 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
s->scale_x = 1.0;
s->scale_y = 1.0;
- gd_resize(s->ds);
+ gd_resize(&s->dcl, s->ds);
}
static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
@@ -775,7 +778,7 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
s->free_scale = FALSE;
}
- gd_resize(s->ds);
+ gd_resize(&s->dcl, s->ds);
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
@@ -1281,6 +1284,13 @@ static void gd_create_menus(GtkDisplayState *s)
gtk_menu_shell_append(GTK_MENU_SHELL(s->menu_bar), s->view_menu_item);
}
+static const DisplayChangeListenerOps dcl_ops = {
+ .dpy_name = "gtk",
+ .dpy_gfx_update = gd_update,
+ .dpy_gfx_resize = gd_resize,
+ .dpy_refresh = gd_refresh,
+};
+
void gtk_display_init(DisplayState *ds)
{
GtkDisplayState *s = g_malloc0(sizeof(*s));
@@ -1289,9 +1299,7 @@ void gtk_display_init(DisplayState *ds)
ds->opaque = s;
s->ds = ds;
- s->dcl.dpy_gfx_update = gd_update;
- s->dcl.dpy_gfx_resize = gd_resize;
- s->dcl.dpy_refresh = gd_refresh;
+ s->dcl.ops = &dcl_ops;
s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#if GTK_CHECK_VERSION(3, 2, 0)
diff --git a/ui/sdl.c b/ui/sdl.c
index 1657848..5baffa0 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -59,7 +59,9 @@ static SDL_PixelFormat host_format;
static int scaling_active = 0;
static Notifier mouse_mode_notifier;
-static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
+static void sdl_update(DisplayChangeListener *dcl,
+ 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);
SDL_Rect rec;
@@ -81,7 +83,8 @@ static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
}
-static void sdl_setdata(DisplayState *ds)
+static void sdl_setdata(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
if (guest_screen != NULL) SDL_FreeSurface(guest_screen);
@@ -114,7 +117,8 @@ static void do_sdl_resize(int width, int height, int bpp)
}
}
-static void sdl_resize(DisplayState *ds)
+static void sdl_resize(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
if (!scaling_active) {
do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
@@ -122,7 +126,7 @@ static void sdl_resize(DisplayState *ds)
do_sdl_resize(real_screen->w, real_screen->h,
ds_get_bits_per_pixel(ds));
}
- sdl_setdata(ds);
+ sdl_setdata(dcl, ds);
}
/* generic keyboard conversion */
@@ -514,7 +518,7 @@ static void handle_keydown(DisplayState *ds, SDL_Event *ev)
case 0x16: /* 'u' key on US keyboard */
if (scaling_active) {
scaling_active = 0;
- sdl_resize(ds);
+ sdl_resize(dcl, ds);
vga_hw_invalidate();
vga_hw_update();
}
@@ -753,7 +757,8 @@ static void handle_activation(DisplayState *ds, SDL_Event *ev)
}
}
-static void sdl_refresh(DisplayState *ds)
+static void sdl_refresh(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
SDL_Event ev1, *ev = &ev1;
@@ -768,7 +773,7 @@ static void sdl_refresh(DisplayState *ds)
while (SDL_PollEvent(ev)) {
switch (ev->type) {
case SDL_VIDEOEXPOSE:
- sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
+ sdl_update(dcl, ds, 0, 0, real_screen->w, real_screen->h);
break;
case SDL_KEYDOWN:
handle_keydown(ds, ev);
@@ -803,7 +808,9 @@ static void sdl_refresh(DisplayState *ds)
}
}
-static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
+static void sdl_mouse_warp(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int x, int y, int on)
{
if (on) {
if (!guest_cursor)
@@ -819,7 +826,9 @@ static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
guest_x = x, guest_y = y;
}
-static void sdl_mouse_define(DisplayState *ds, QEMUCursor *c)
+static void sdl_mouse_define(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ QEMUCursor *c)
{
uint8_t *image, *mask;
int bpl;
@@ -849,6 +858,16 @@ static void sdl_cleanup(void)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
+static const DisplayChangeListenerOps dcl_ops = {
+ .dpy_name = "sdl",
+ .dpy_gfx_update = sdl_update,
+ .dpy_gfx_resize = sdl_resize,
+ .dpy_refresh = sdl_refresh,
+ .dpy_gfx_setdata = sdl_setdata,
+ .dpy_mouse_set = sdl_mouse_warp,
+ .dpy_cursor_define = sdl_mouse_define,
+};
+
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
{
int flags;
@@ -917,12 +936,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
}
dcl = g_malloc0(sizeof(DisplayChangeListener));
- dcl->dpy_gfx_update = sdl_update;
- dcl->dpy_gfx_resize = sdl_resize;
- dcl->dpy_refresh = sdl_refresh;
- dcl->dpy_gfx_setdata = sdl_setdata;
- dcl->dpy_mouse_set = sdl_mouse_warp;
- dcl->dpy_cursor_define = sdl_mouse_define;
+ dcl->ops = &dcl_ops;
register_displaychangelistener(ds, dcl);
mouse_mode_notifier.notify = sdl_mouse_mode_change;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index dc7e58d..b6528fa 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -583,25 +583,30 @@ static const QXLInterface dpy_interface = {
static SimpleSpiceDisplay sdpy;
-static void display_update(struct DisplayState *ds, int x, int y, int w, int h)
+static void display_update(DisplayChangeListener *dcl,
+ struct DisplayState *ds,
+ int x, int y, int w, int h)
{
qemu_spice_display_update(&sdpy, x, y, w, h);
}
-static void display_resize(struct DisplayState *ds)
+static void display_resize(DisplayChangeListener *dcl,
+ struct DisplayState *ds)
{
qemu_spice_display_resize(&sdpy);
}
-static void display_refresh(struct DisplayState *ds)
+static void display_refresh(DisplayChangeListener *dcl,
+ struct DisplayState *ds)
{
qemu_spice_display_refresh(&sdpy);
}
-static DisplayChangeListener display_listener = {
+static const DisplayChangeListenerOps display_listener_ops = {
+ .dpy_name = "spice",
.dpy_gfx_update = display_update,
.dpy_gfx_resize = display_resize,
- .dpy_refresh = display_refresh,
+ .dpy_refresh = display_refresh,
};
void qemu_spice_display_init(DisplayState *ds)
@@ -615,5 +620,7 @@ void qemu_spice_display_init(DisplayState *ds)
qemu_spice_create_host_memslot(&sdpy);
qemu_spice_create_host_primary(&sdpy);
- register_displaychangelistener(ds, &display_listener);
+
+ sdpy.dcl.ops = &display_listener_ops;
+ register_displaychangelistener(ds, &sdpy.dcl);
}
diff --git a/ui/vnc.c b/ui/vnc.c
index ff4e2ae..bdc3cd8 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -430,7 +430,9 @@ static void framebuffer_update_request(VncState *vs, int incremental,
static void vnc_refresh(void *opaque);
static int vnc_refresh_server_surface(VncDisplay *vd);
-static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
+static void vnc_dpy_update(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int x, int y, int w, int h)
{
int i;
VncDisplay *vd = ds->opaque;
@@ -573,7 +575,8 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
return ptr;
}
-static void vnc_dpy_resize(DisplayState *ds)
+static void vnc_dpy_resize(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
VncDisplay *vd = ds->opaque;
VncState *vs;
@@ -735,7 +738,10 @@ static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, i
vnc_flush(vs);
}
-static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
+static void vnc_dpy_copy(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int src_x, int src_y,
+ int dst_x, int dst_y, int w, int h)
{
VncDisplay *vd = ds->opaque;
VncState *vs, *vn;
@@ -806,7 +812,9 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
}
}
-static void vnc_mouse_set(DisplayState *ds, int x, int y, int visible)
+static void vnc_mouse_set(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ int x, int y, int visible)
{
/* can we ask the client(s) to move the pointer ??? */
}
@@ -832,7 +840,9 @@ static int vnc_cursor_define(VncState *vs)
return -1;
}
-static void vnc_dpy_cursor_define(DisplayState *ds, QEMUCursor *c)
+static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ QEMUCursor *c)
{
VncDisplay *vd = vnc_display;
VncState *vs;
@@ -1972,14 +1982,15 @@ static void pixel_format_message (VncState *vs) {
vs->write_pixels = vnc_write_pixels_copy;
}
-static void vnc_dpy_setdata(DisplayState *ds)
+static void vnc_dpy_setdata(DisplayChangeListener *dcl,
+ DisplayState *ds)
{
VncDisplay *vd = ds->opaque;
qemu_pixman_image_unref(vd->guest.fb);
vd->guest.fb = pixman_image_ref(ds->surface->image);
vd->guest.format = ds->surface->format;
- vnc_dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
+ vnc_dpy_update(dcl, ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
}
static void vnc_colordepth(VncState *vs)
@@ -2686,7 +2697,7 @@ static void vnc_init_timer(VncDisplay *vd)
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- vnc_dpy_resize(vd->ds);
+ vnc_dpy_resize(dcl, vd->ds);
vnc_refresh(vd);
}
}
@@ -2822,6 +2833,16 @@ static void vnc_listen_websocket_read(void *opaque)
}
#endif /* CONFIG_VNC_WS */
+static const DisplayChangeListenerOps dcl_ops = {
+ .dpy_name = "vnc",
+ .dpy_gfx_copy = vnc_dpy_copy,
+ .dpy_gfx_update = vnc_dpy_update,
+ .dpy_gfx_resize = vnc_dpy_resize,
+ .dpy_gfx_setdata = vnc_dpy_setdata,
+ .dpy_mouse_set = vnc_mouse_set,
+ .dpy_cursor_define = vnc_dpy_cursor_define,
+};
+
void vnc_display_init(DisplayState *ds)
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
@@ -2852,12 +2873,7 @@ void vnc_display_init(DisplayState *ds)
qemu_mutex_init(&vs->mutex);
vnc_start_worker_thread();
- dcl->dpy_gfx_copy = vnc_dpy_copy;
- dcl->dpy_gfx_update = vnc_dpy_update;
- dcl->dpy_gfx_resize = vnc_dpy_resize;
- dcl->dpy_gfx_setdata = vnc_dpy_setdata;
- dcl->dpy_mouse_set = vnc_mouse_set;
- dcl->dpy_cursor_define = vnc_dpy_cursor_define;
+ dcl->ops = &dcl_ops;
register_displaychangelistener(ds, dcl);
}
diff --git a/vl.c b/vl.c
index febd2ea..e89cd79 100644
--- a/vl.c
+++ b/vl.c
@@ -1613,13 +1613,13 @@ void gui_setup_refresh(DisplayState *ds)
bool have_text = false;
QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->dpy_refresh != NULL) {
+ if (dcl->ops->dpy_refresh != NULL) {
need_timer = true;
}
- if (dcl->dpy_gfx_update != NULL) {
+ if (dcl->ops->dpy_gfx_update != NULL) {
have_gfx = true;
}
- if (dcl->dpy_text_update != NULL) {
+ if (dcl->ops->dpy_text_update != NULL) {
have_text = true;
}
}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 02/12] console: kill DisplayState->opaque
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 01/12] console: fix displaychangelisteners interface Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 03/12] spice: zap sdpy global Gerd Hoffmann
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
It's broken by design. There can be multiple DisplayChangeListener
instances, so they simply can't store state in the (single) DisplayState
struct. Try 'qemu -display gtk -vnc :0', watch it crash & burn.
With DisplayChangeListenerOps having a more sane interface now we can
simply use the DisplayChangeListener pointer to get access to our
private data instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 1 -
ui/gtk.c | 5 ++---
ui/vnc.c | 38 +++++++++++++++++---------------------
ui/vnc.h | 1 +
4 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index 695eabb..0fe9e50 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -193,7 +193,6 @@ struct DisplayChangeListener {
struct DisplayState {
struct DisplaySurface *surface;
- void *opaque;
struct QEMUTimer *gui_timer;
bool have_gfx;
bool have_text;
diff --git a/ui/gtk.c b/ui/gtk.c
index e89d4b1..fe58494 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -230,7 +230,7 @@ static void gd_update_caption(GtkDisplayState *s)
static void gd_update(DisplayChangeListener *dcl,
DisplayState *ds, int x, int y, int w, int h)
{
- GtkDisplayState *s = ds->opaque;
+ GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
int x1, x2, y1, y2;
int mx, my;
int fbw, fbh;
@@ -269,7 +269,7 @@ static void gd_refresh(DisplayChangeListener *dcl,
static void gd_resize(DisplayChangeListener *dcl,
DisplayState *ds)
{
- GtkDisplayState *s = ds->opaque;
+ GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
cairo_format_t kind;
int stride;
@@ -1297,7 +1297,6 @@ void gtk_display_init(DisplayState *ds)
gtk_init(NULL, NULL);
- ds->opaque = s;
s->ds = ds;
s->dcl.ops = &dcl_ops;
diff --git a/ui/vnc.c b/ui/vnc.c
index bdc3cd8..a6111d6 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -44,7 +44,6 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
#include "d3des.h"
static VncDisplay *vnc_display; /* needed for info vnc */
-static DisplayChangeListener *dcl;
static int vnc_cursor_define(VncState *vs);
static void vnc_release_modifiers(VncState *vs);
@@ -435,7 +434,7 @@ static void vnc_dpy_update(DisplayChangeListener *dcl,
int x, int y, int w, int h)
{
int i;
- VncDisplay *vd = ds->opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
struct VncSurface *s = &vd->guest;
int width = ds_get_width(ds);
int height = ds_get_height(ds);
@@ -578,7 +577,7 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
static void vnc_dpy_resize(DisplayChangeListener *dcl,
DisplayState *ds)
{
- VncDisplay *vd = ds->opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs;
vnc_abort_display_jobs(vd);
@@ -743,7 +742,7 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl,
int src_x, int src_y,
int dst_x, int dst_y, int w, int h)
{
- VncDisplay *vd = ds->opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs, *vn;
uint8_t *src_row;
uint8_t *dst_row;
@@ -1069,7 +1068,7 @@ void vnc_disconnect_finish(VncState *vs)
}
if (QTAILQ_EMPTY(&vs->vd->clients)) {
- dcl->idle = 1;
+ vs->vd->dcl.idle = 1;
}
vnc_remove_timer(vs->vd);
@@ -1985,7 +1984,7 @@ static void pixel_format_message (VncState *vs) {
static void vnc_dpy_setdata(DisplayChangeListener *dcl,
DisplayState *ds)
{
- VncDisplay *vd = ds->opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
qemu_pixman_image_unref(vd->guest.fb);
vd->guest.fb = pixman_image_ref(ds->surface->image);
@@ -2697,7 +2696,7 @@ static void vnc_init_timer(VncDisplay *vd)
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- vnc_dpy_resize(dcl, vd->ds);
+ vnc_dpy_resize(&vd->dcl, vd->ds);
vnc_refresh(vd);
}
}
@@ -2736,7 +2735,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket)
}
VNC_DEBUG("New client on socket %d\n", csock);
- dcl->idle = 0;
+ vd->dcl.idle = 0;
socket_set_nonblock(vs->csock);
#ifdef CONFIG_VNC_WS
if (websocket) {
@@ -2847,10 +2846,7 @@ void vnc_display_init(DisplayState *ds)
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
- dcl = g_malloc0(sizeof(DisplayChangeListener));
-
- ds->opaque = vs;
- dcl->idle = 1;
+ vs->dcl.idle = 1;
vnc_display = vs;
vs->lsock = -1;
@@ -2873,14 +2869,14 @@ void vnc_display_init(DisplayState *ds)
qemu_mutex_init(&vs->mutex);
vnc_start_worker_thread();
- dcl->ops = &dcl_ops;
- register_displaychangelistener(ds, dcl);
+ vs->dcl.ops = &dcl_ops;
+ register_displaychangelistener(ds, &vs->dcl);
}
static void vnc_display_close(DisplayState *ds)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs)
return;
@@ -2911,7 +2907,7 @@ static void vnc_display_close(DisplayState *ds)
static int vnc_display_disable_login(DisplayState *ds)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs) {
return -1;
@@ -2931,7 +2927,7 @@ static int vnc_display_disable_login(DisplayState *ds)
int vnc_display_password(DisplayState *ds, const char *password)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs) {
return -EINVAL;
@@ -2957,7 +2953,7 @@ int vnc_display_password(DisplayState *ds, const char *password)
int vnc_display_pw_expire(DisplayState *ds, time_t expires)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
if (!vs) {
return -EINVAL;
@@ -2969,14 +2965,14 @@ int vnc_display_pw_expire(DisplayState *ds, time_t expires)
char *vnc_display_local_addr(DisplayState *ds)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
return vnc_socket_local_addr("%s:%s", vs->lsock);
}
void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
const char *options;
int password = 0;
int reverse = 0;
@@ -3282,7 +3278,7 @@ fail:
void vnc_display_add_client(DisplayState *ds, int csock, int skipauth)
{
- VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
+ VncDisplay *vs = vnc_display;
vnc_connect(vs, csock, skipauth, 0);
}
diff --git a/ui/vnc.h b/ui/vnc.h
index 45d7686..a96485b 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -151,6 +151,7 @@ struct VncDisplay
char *ws_display;
#endif
DisplayState *ds;
+ DisplayChangeListener dcl;
kbd_layout_t *kbd_layout;
int lock_key_sync;
QemuMutex mutex;
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 03/12] spice: zap sdpy global
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 01/12] console: fix displaychangelisteners interface Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 02/12] console: kill DisplayState->opaque Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 04/12] qxl: zap qxl0 global Gerd Hoffmann
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
DisplayChangeListener is passed now to all DisplayChangeListenerOps
callbacks, so we can use that to access the spice display state and
kill the sdpy global variable.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/spice-display.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index b6528fa..b2bda23 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -581,25 +581,26 @@ static const QXLInterface dpy_interface = {
.client_monitors_config = interface_client_monitors_config,
};
-static SimpleSpiceDisplay sdpy;
-
static void display_update(DisplayChangeListener *dcl,
struct DisplayState *ds,
int x, int y, int w, int h)
{
- qemu_spice_display_update(&sdpy, x, y, w, h);
+ SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+ qemu_spice_display_update(ssd, x, y, w, h);
}
static void display_resize(DisplayChangeListener *dcl,
struct DisplayState *ds)
{
- qemu_spice_display_resize(&sdpy);
+ SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+ qemu_spice_display_resize(ssd);
}
static void display_refresh(DisplayChangeListener *dcl,
struct DisplayState *ds)
{
- qemu_spice_display_refresh(&sdpy);
+ SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
+ qemu_spice_display_refresh(ssd);
}
static const DisplayChangeListenerOps display_listener_ops = {
@@ -611,16 +612,17 @@ static const DisplayChangeListenerOps display_listener_ops = {
void qemu_spice_display_init(DisplayState *ds)
{
- assert(sdpy.ds == NULL);
- qemu_spice_display_init_common(&sdpy, ds);
+ SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
+
+ qemu_spice_display_init_common(ssd, ds);
- sdpy.qxl.base.sif = &dpy_interface.base;
- qemu_spice_add_interface(&sdpy.qxl.base);
- assert(sdpy.worker);
+ ssd->qxl.base.sif = &dpy_interface.base;
+ qemu_spice_add_interface(&ssd->qxl.base);
+ assert(ssd->worker);
- qemu_spice_create_host_memslot(&sdpy);
- qemu_spice_create_host_primary(&sdpy);
+ qemu_spice_create_host_memslot(ssd);
+ qemu_spice_create_host_primary(ssd);
- sdpy.dcl.ops = &display_listener_ops;
- register_displaychangelistener(ds, &sdpy.dcl);
+ ssd->dcl.ops = &display_listener_ops;
+ register_displaychangelistener(ds, &ssd->dcl);
}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 04/12] qxl: zap qxl0 global
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (2 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 03/12] spice: zap sdpy global Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 05/12] qxl: better vga init in enter_vga_mode Gerd Hoffmann
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
DisplayChangeListener is passed now to all DisplayChangeListenerOps
callbacks, so we can use that to access the qxl state and kill the
qxl0 global variable.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qxl.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index cb3d317..cc0ba40 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -118,8 +118,6 @@ static QXLMode qxl_modes[] = {
QXL_MODE_EX(3200, 2400),
};
-static PCIQXLDevice *qxl0;
-
static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
static void qxl_reset_memslots(PCIQXLDevice *d);
@@ -1870,28 +1868,34 @@ static void display_update(DisplayChangeListener *dcl,
struct DisplayState *ds,
int x, int y, int w, int h)
{
- if (qxl0->mode == QXL_MODE_VGA) {
- qemu_spice_display_update(&qxl0->ssd, x, y, w, h);
+ PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
+
+ if (qxl->mode == QXL_MODE_VGA) {
+ qemu_spice_display_update(&qxl->ssd, x, y, w, h);
}
}
static void display_resize(DisplayChangeListener *dcl,
struct DisplayState *ds)
{
- if (qxl0->mode == QXL_MODE_VGA) {
- qemu_spice_display_resize(&qxl0->ssd);
+ PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
+
+ if (qxl->mode == QXL_MODE_VGA) {
+ qemu_spice_display_resize(&qxl->ssd);
}
}
static void display_refresh(DisplayChangeListener *dcl,
struct DisplayState *ds)
{
- if (qxl0->mode == QXL_MODE_VGA) {
- qemu_spice_display_refresh(&qxl0->ssd);
+ PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
+
+ if (qxl->mode == QXL_MODE_VGA) {
+ qemu_spice_display_refresh(&qxl->ssd);
} else {
- qemu_mutex_lock(&qxl0->ssd.lock);
- qemu_spice_cursor_refresh_unlocked(&qxl0->ssd);
- qemu_mutex_unlock(&qxl0->ssd.lock);
+ qemu_mutex_lock(&qxl->ssd.lock);
+ qemu_spice_cursor_refresh_unlocked(&qxl->ssd);
+ qemu_mutex_unlock(&qxl->ssd.lock);
}
}
@@ -2074,8 +2078,6 @@ static int qxl_init_primary(PCIDevice *dev)
qxl_hw_screen_dump, qxl_hw_text_update, qxl);
qemu_spice_display_init_common(&qxl->ssd, vga->ds);
- qxl0 = qxl;
-
rc = qxl_init_common(qxl);
if (rc != 0) {
return rc;
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 05/12] qxl: better vga init in enter_vga_mode
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (3 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 04/12] qxl: zap qxl0 global Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 06/12] sdl: drop dead code Gerd Hoffmann
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Ask the vga core to update the display. Will trigger dpy_gfx_resize
if needed. More complete than just calling dpy_gfx_resize.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qxl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index cc0ba40..8177008 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1073,8 +1073,8 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
trace_qxl_enter_vga_mode(d->id);
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
- dpy_gfx_resize(d->ssd.ds);
vga_dirty_log_start(&d->vga);
+ vga_hw_update();
}
static void qxl_exit_vga_mode(PCIQXLDevice *d)
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 06/12] sdl: drop dead code
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (4 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 05/12] qxl: better vga init in enter_vga_mode Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 07/12] console: rework DisplaySurface handling [vga emu side] Gerd Hoffmann
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
DisplayAllocator removal made this a nop.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/sdl.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/ui/sdl.c b/ui/sdl.c
index 5baffa0..fc4dc1b 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -458,11 +458,6 @@ static void sdl_scale(DisplayState *ds, int width, int height)
}
do_sdl_resize(width, height, bpp);
scaling_active = 1;
- if (!is_buffer_shared(ds->surface)) {
- ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds),
- ds_get_height(ds));
- dpy_gfx_resize(ds);
- }
}
static void toggle_full_screen(DisplayState *ds)
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 07/12] console: rework DisplaySurface handling [vga emu side]
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (5 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 06/12] sdl: drop dead code Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 08/12] console: rework DisplaySurface handling [dcl/ui side] Gerd Hoffmann
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Decouple DisplaySurface allocation & deallocation from DisplayState.
Replace dpy_gfx_resize + dpy_gfx_setdata with a dpy_gfx_replace_surface
function.
This handles the graphic hardware emulation.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/nseries.c | 7 -----
hw/palm.c | 7 -----
hw/qxl-render.c | 12 ++++-----
hw/vga.c | 17 ++++++------
include/ui/console.h | 11 +++-----
trace-events | 5 ++--
ui/console.c | 71 +++++++++++++++++++++-----------------------------
7 files changed, 50 insertions(+), 80 deletions(-)
diff --git a/hw/nseries.c b/hw/nseries.c
index 99d353a..9b6b51d 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1290,7 +1290,6 @@ static void n8x0_init(QEMUMachineInitArgs *args,
MemoryRegion *sysmem = get_system_memory();
struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
int sdram_size = binfo->ram_size;
- DisplayState *ds;
s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model);
@@ -1370,12 +1369,6 @@ static void n8x0_init(QEMUMachineInitArgs *args,
n800_setup_nolo_tags(nolo_tags);
cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
}
- /* 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. */
- ds = get_displaystate();
- ds->surface = qemu_resize_displaysurface(ds, 800, 480);
- dpy_gfx_resize(ds);
}
static struct arm_boot_info n800_binfo = {
diff --git a/hw/palm.c b/hw/palm.c
index a633dfc..f86e1b0 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -205,7 +205,6 @@ static void palmte_init(QEMUMachineInitArgs *args)
static uint32_t cs2val = 0x0000e1a0;
static uint32_t cs3val = 0xe1a0e1a0;
int rom_size, rom_loaded = 0;
- DisplayState *ds = get_displaystate();
MemoryRegion *flash = g_new(MemoryRegion, 1);
MemoryRegion *cs = g_new(MemoryRegion, 4);
@@ -268,12 +267,6 @@ static void palmte_init(QEMUMachineInitArgs *args)
palmte_binfo.initrd_filename = initrd_filename;
arm_load_kernel(mpu->cpu, &palmte_binfo);
}
-
- /* 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. */
- ds->surface = qemu_resize_displaysurface(ds, 320, 320);
- dpy_gfx_resize(ds);
}
static QEMUMachine palmte_machine = {
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 455fb91..7172d9a 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -98,6 +98,7 @@ static void qxl_set_rect_to_surface(PCIQXLDevice *qxl, QXLRect *area)
static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
{
VGACommonState *vga = &qxl->vga;
+ DisplaySurface *surface;
int i;
if (qxl->guest_primary.resized) {
@@ -112,8 +113,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.bytes_pp,
qxl->guest_primary.bits_pp);
if (qxl->guest_primary.qxl_stride > 0) {
- qemu_free_displaysurface(vga->ds);
- vga->ds->surface = qemu_create_displaysurface_from
+ surface = qemu_create_displaysurface_from
(qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height,
qxl->guest_primary.bits_pp,
@@ -121,11 +121,11 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.data,
false);
} else {
- qemu_resize_displaysurface(vga->ds,
- qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height);
+ surface = qemu_create_displaysurface
+ (qxl->guest_primary.surface.width,
+ qxl->guest_primary.surface.height);
}
- dpy_gfx_resize(vga->ds);
+ dpy_gfx_replace_surface(vga->ds, surface);
}
for (i = 0; i < qxl->num_dirty_rects; i++) {
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
diff --git a/hw/vga.c b/hw/vga.c
index 1caf23d..65471c6 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1691,11 +1691,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
height != s->last_height ||
s->last_depth != depth) {
if (depth == 32 || (depth == 16 && !byteswap)) {
- qemu_free_displaysurface(s->ds);
- s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
- s->line_offset,
+ DisplaySurface *surface;
+ surface = qemu_create_displaysurface_from(disp_width,
+ height, depth, s->line_offset,
s->vram_ptr + (s->start_addr * 4), byteswap);
- dpy_gfx_resize(s->ds);
+ dpy_gfx_replace_surface(s->ds, surface);
} else {
qemu_console_resize(s->ds, disp_width, height);
}
@@ -1709,12 +1709,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
} else if (is_buffer_shared(s->ds->surface) &&
(full_update || ds_get_data(s->ds) != s->vram_ptr
+ (s->start_addr * 4))) {
- qemu_free_displaysurface(s->ds);
- s->ds->surface = qemu_create_displaysurface_from(disp_width,
- height, depth,
- s->line_offset,
+ DisplaySurface *surface;
+ surface = qemu_create_displaysurface_from(disp_width,
+ height, depth, s->line_offset,
s->vram_ptr + (s->start_addr * 4), byteswap);
- dpy_gfx_setdata(s->ds);
+ dpy_gfx_replace_surface(s->ds, surface);
}
s->rgb_to_pixel =
diff --git a/include/ui/console.h b/include/ui/console.h
index 0fe9e50..bbf3b1d 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -210,11 +210,8 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
PixelFormat qemu_different_endianness_pixelformat(int bpp);
PixelFormat qemu_default_pixelformat(int bpp);
-DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
- int width, int height);
-DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
- int width, int height);
-void qemu_free_displaysurface(DisplayState *ds);
+DisplaySurface *qemu_create_displaysurface(int width, int height);
+void qemu_free_displaysurface(DisplaySurface *surface);
static inline int is_surface_bgr(DisplaySurface *surface)
{
@@ -236,8 +233,8 @@ void register_displaychangelistener(DisplayState *ds,
void unregister_displaychangelistener(DisplayChangeListener *dcl);
void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h);
-void dpy_gfx_resize(DisplayState *s);
-void dpy_gfx_setdata(DisplayState *s);
+void dpy_gfx_replace_surface(DisplayState *s,
+ DisplaySurface *surface);
void dpy_refresh(DisplayState *s);
void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
int dst_x, int dst_y, int w, int h);
diff --git a/trace-events b/trace-events
index 984d7e3..93b0650 100644
--- a/trace-events
+++ b/trace-events
@@ -956,8 +956,9 @@ dma_bdrv_cb(void *dbs, int ret) "dbs=%p ret=%d"
dma_map_wait(void *dbs) "dbs=%p"
# console.h
-displaysurface_free(void *display_state, void *display_surface) "state=%p surface=%p"
-displaysurface_resize(void *display_state, void *display_surface, int width, int height) "state=%p surface=%p %dx%d"
+displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
+displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
+displaysurface_free(void *display_surface) "surface=%p"
displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
diff --git a/ui/console.c b/ui/console.c
index b0bc9e2..54c7bf3 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1099,8 +1099,9 @@ void console_select(unsigned int index)
}
active_console = s;
if (ds->have_gfx) {
- ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
- dpy_gfx_resize(ds);
+ DisplaySurface *surface;
+ surface = qemu_create_displaysurface(s->g_width, s->g_height);
+ dpy_gfx_replace_surface(ds, surface);
}
if (ds->have_text) {
dpy_text_resize(ds, s->width, s->height);
@@ -1316,34 +1317,24 @@ static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
#endif
}
-DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
- int width, int height)
+DisplaySurface *qemu_create_displaysurface(int width, int height)
{
DisplaySurface *surface = g_new0(DisplaySurface, 1);
-
int linesize = width * 4;
+
+ trace_displaysurface_create(surface, width, height);
qemu_alloc_display(surface, width, height, linesize,
qemu_default_pixelformat(32), 0);
return surface;
}
-DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
- int width, int height)
-{
- int linesize = width * 4;
-
- trace_displaysurface_resize(ds, ds->surface, width, height);
- qemu_alloc_display(ds->surface, width, height, linesize,
- qemu_default_pixelformat(32), 0);
- return ds->surface;
-}
-
DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data,
bool byteswap)
{
DisplaySurface *surface = g_new0(DisplaySurface, 1);
+ trace_displaysurface_create_from(surface, width, height, bpp, byteswap);
if (byteswap) {
surface->pf = qemu_different_endianness_pixelformat(bpp);
} else {
@@ -1364,14 +1355,14 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
return surface;
}
-void qemu_free_displaysurface(DisplayState *ds)
+void qemu_free_displaysurface(DisplaySurface *surface)
{
- trace_displaysurface_free(ds, ds->surface);
- if (ds->surface == NULL) {
+ if (surface == NULL) {
return;
}
- qemu_pixman_image_unref(ds->surface->image);
- g_free(ds->surface);
+ trace_displaysurface_free(surface);
+ qemu_pixman_image_unref(surface->image);
+ g_free(surface);
}
void register_displaychangelistener(DisplayState *ds,
@@ -1414,24 +1405,19 @@ void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
}
}
-void dpy_gfx_resize(DisplayState *s)
+void dpy_gfx_replace_surface(DisplayState *s,
+ DisplaySurface *surface)
{
+ DisplaySurface *old_surface = s->surface;
struct DisplayChangeListener *dcl;
+
+ s->surface = surface;
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_gfx_resize) {
dcl->ops->dpy_gfx_resize(dcl, s);
}
}
-}
-
-void dpy_gfx_setdata(DisplayState *s)
-{
- struct DisplayChangeListener *dcl;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->ops->dpy_gfx_setdata) {
- dcl->ops->dpy_gfx_setdata(dcl, s);
- }
- }
+ qemu_free_displaysurface(old_surface);
}
void dpy_refresh(DisplayState *s)
@@ -1521,6 +1507,7 @@ bool dpy_cursor_define_supported(struct DisplayState *s)
static void dumb_display_init(void)
{
DisplayState *ds = g_malloc0(sizeof(DisplayState));
+ DisplaySurface *surface;
int width = 640;
int height = 480;
@@ -1528,7 +1515,9 @@ static void dumb_display_init(void)
width = active_console->g_width;
height = active_console->g_height;
}
- ds->surface = qemu_create_displaysurface(ds, width, height);
+ surface = qemu_create_displaysurface(width, height);
+ dpy_gfx_replace_surface(ds, surface);
+
register_displaystate(ds);
}
@@ -1561,22 +1550,19 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
{
QemuConsole *s;
DisplayState *ds;
+ DisplaySurface *surface;
ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
- ds->surface = qemu_create_displaysurface(ds, 640, 480);
-
s = new_console(ds, GRAPHIC_CONSOLE);
- if (s == NULL) {
- qemu_free_displaysurface(ds);
- g_free(ds);
- return NULL;
- }
s->hw_update = update;
s->hw_invalidate = invalidate;
s->hw_screen_dump = screen_dump;
s->hw_text_update = text_update;
s->hw = opaque;
+ surface = qemu_create_displaysurface(640, 480);
+ dpy_gfx_replace_surface(ds, surface);
+
register_displaystate(ds);
return ds;
}
@@ -1748,8 +1734,9 @@ void qemu_console_resize(DisplayState *ds, int width, int height)
s->g_width = width;
s->g_height = height;
if (is_graphic_console()) {
- ds->surface = qemu_resize_displaysurface(ds, width, height);
- dpy_gfx_resize(ds);
+ DisplaySurface *surface;
+ surface = qemu_create_displaysurface(width, height);
+ dpy_gfx_replace_surface(ds, surface);
}
}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 08/12] console: rework DisplaySurface handling [dcl/ui side]
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (6 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 07/12] console: rework DisplaySurface handling [vga emu side] Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 09/12] console: add surface_*() getters Gerd Hoffmann
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Replace the dpy_gfx_resize and dpy_gfx_setdata DisplayChangeListener
callbacks with a dpy_gfx_switch callback which notifies the ui code
when the framebuffer backing storage changes.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qxl.c | 9 +++++----
include/ui/console.h | 7 +++----
include/ui/spice-display.h | 3 ++-
ui/console.c | 8 ++++----
ui/gtk.c | 15 ++++++++-------
ui/sdl.c | 10 +++++-----
ui/spice-display.c | 12 +++++++-----
ui/vnc.c | 21 +++++----------------
8 files changed, 39 insertions(+), 46 deletions(-)
diff --git a/hw/qxl.c b/hw/qxl.c
index 8177008..1ec03a5 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1875,13 +1875,14 @@ static void display_update(DisplayChangeListener *dcl,
}
}
-static void display_resize(DisplayChangeListener *dcl,
- struct DisplayState *ds)
+static void display_switch(DisplayChangeListener *dcl,
+ struct DisplayState *ds,
+ struct DisplaySurface *surface)
{
PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
if (qxl->mode == QXL_MODE_VGA) {
- qemu_spice_display_resize(&qxl->ssd);
+ qemu_spice_display_switch(&qxl->ssd, surface);
}
}
@@ -1902,7 +1903,7 @@ static void display_refresh(DisplayChangeListener *dcl,
static DisplayChangeListenerOps display_listener_ops = {
.dpy_name = "spice/qxl",
.dpy_gfx_update = display_update,
- .dpy_gfx_resize = display_resize,
+ .dpy_gfx_switch = display_switch,
.dpy_refresh = display_refresh,
};
diff --git a/include/ui/console.h b/include/ui/console.h
index bbf3b1d..f15a541 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -156,10 +156,9 @@ typedef struct DisplayChangeListenerOps {
void (*dpy_gfx_update)(DisplayChangeListener *dcl,
struct DisplayState *s,
int x, int y, int w, int h);
- void (*dpy_gfx_resize)(DisplayChangeListener *dcl,
- struct DisplayState *s);
- void (*dpy_gfx_setdata)(DisplayChangeListener *dcl,
- struct DisplayState *s);
+ void (*dpy_gfx_switch)(DisplayChangeListener *dcl,
+ struct DisplayState *s,
+ struct DisplaySurface *new_surface);
void (*dpy_gfx_copy)(DisplayChangeListener *dcl,
struct DisplayState *s, int src_x, int src_y,
int dst_x, int dst_y, int w, int h);
diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index f2752aa..82f8246 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -117,7 +117,8 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
int x, int y, int w, int h);
-void qemu_spice_display_resize(SimpleSpiceDisplay *ssd);
+void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
+ DisplaySurface *surface);
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd);
void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd);
diff --git a/ui/console.c b/ui/console.c
index 54c7bf3..461cda8 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1372,8 +1372,8 @@ void register_displaychangelistener(DisplayState *ds,
dcl->ds = ds;
QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
gui_setup_refresh(ds);
- if (dcl->ops->dpy_gfx_resize) {
- dcl->ops->dpy_gfx_resize(dcl, ds);
+ if (dcl->ops->dpy_gfx_switch) {
+ dcl->ops->dpy_gfx_switch(dcl, ds, ds->surface);
}
}
@@ -1413,8 +1413,8 @@ void dpy_gfx_replace_surface(DisplayState *s,
s->surface = surface;
QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->ops->dpy_gfx_resize) {
- dcl->ops->dpy_gfx_resize(dcl, s);
+ if (dcl->ops->dpy_gfx_switch) {
+ dcl->ops->dpy_gfx_switch(dcl, s, surface);
}
}
qemu_free_displaysurface(old_surface);
diff --git a/ui/gtk.c b/ui/gtk.c
index fe58494..abef1ca 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -266,8 +266,9 @@ static void gd_refresh(DisplayChangeListener *dcl,
vga_hw_update();
}
-static void gd_resize(DisplayChangeListener *dcl,
- DisplayState *ds)
+static void gd_switch(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ DisplaySurface *surface)
{
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
cairo_format_t kind;
@@ -738,7 +739,7 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
s->scale_x += .25;
s->scale_y += .25;
- gd_resize(&s->dcl, s->ds);
+ gd_switch(&s->dcl, s->ds, s->ds->surface);
}
static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
@@ -754,7 +755,7 @@ static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
s->scale_x = MAX(s->scale_x, .25);
s->scale_y = MAX(s->scale_y, .25);
- gd_resize(&s->dcl, s->ds);
+ gd_switch(&s->dcl, s->ds, s->ds->surface);
}
static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
@@ -764,7 +765,7 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
s->scale_x = 1.0;
s->scale_y = 1.0;
- gd_resize(&s->dcl, s->ds);
+ gd_switch(&s->dcl, s->ds, s->ds->surface);
}
static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
@@ -778,7 +779,7 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
s->free_scale = FALSE;
}
- gd_resize(&s->dcl, s->ds);
+ gd_switch(&s->dcl, s->ds, s->ds->surface);
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
@@ -1287,7 +1288,7 @@ static void gd_create_menus(GtkDisplayState *s)
static const DisplayChangeListenerOps dcl_ops = {
.dpy_name = "gtk",
.dpy_gfx_update = gd_update,
- .dpy_gfx_resize = gd_resize,
+ .dpy_gfx_switch = gd_switch,
.dpy_refresh = gd_refresh,
};
diff --git a/ui/sdl.c b/ui/sdl.c
index fc4dc1b..85eefdf 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -117,8 +117,9 @@ static void do_sdl_resize(int width, int height, int bpp)
}
}
-static void sdl_resize(DisplayChangeListener *dcl,
- DisplayState *ds)
+static void sdl_switch(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ DisplaySurface *surface)
{
if (!scaling_active) {
do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
@@ -513,7 +514,7 @@ static void handle_keydown(DisplayState *ds, SDL_Event *ev)
case 0x16: /* 'u' key on US keyboard */
if (scaling_active) {
scaling_active = 0;
- sdl_resize(dcl, ds);
+ sdl_switch(dcl, ds, ds->surface);
vga_hw_invalidate();
vga_hw_update();
}
@@ -856,9 +857,8 @@ static void sdl_cleanup(void)
static const DisplayChangeListenerOps dcl_ops = {
.dpy_name = "sdl",
.dpy_gfx_update = sdl_update,
- .dpy_gfx_resize = sdl_resize,
+ .dpy_gfx_switch = sdl_switch,
.dpy_refresh = sdl_refresh,
- .dpy_gfx_setdata = sdl_setdata,
.dpy_mouse_set = sdl_mouse_warp,
.dpy_cursor_define = sdl_mouse_define,
};
diff --git a/ui/spice-display.c b/ui/spice-display.c
index b2bda23..cc2a78e 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -367,7 +367,8 @@ void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
qemu_spice_rect_union(&ssd->dirty, &update_area);
}
-void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
+void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
+ DisplaySurface *surface)
{
SimpleSpiceUpdate *update;
@@ -589,11 +590,12 @@ static void display_update(DisplayChangeListener *dcl,
qemu_spice_display_update(ssd, x, y, w, h);
}
-static void display_resize(DisplayChangeListener *dcl,
- struct DisplayState *ds)
+static void display_switch(DisplayChangeListener *dcl,
+ struct DisplayState *ds,
+ struct DisplaySurface *surface)
{
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
- qemu_spice_display_resize(ssd);
+ qemu_spice_display_switch(ssd, surface);
}
static void display_refresh(DisplayChangeListener *dcl,
@@ -606,7 +608,7 @@ static void display_refresh(DisplayChangeListener *dcl,
static const DisplayChangeListenerOps display_listener_ops = {
.dpy_name = "spice",
.dpy_gfx_update = display_update,
- .dpy_gfx_resize = display_resize,
+ .dpy_gfx_switch = display_switch,
.dpy_refresh = display_refresh,
};
diff --git a/ui/vnc.c b/ui/vnc.c
index a6111d6..f8398c3 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -574,8 +574,9 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
return ptr;
}
-static void vnc_dpy_resize(DisplayChangeListener *dcl,
- DisplayState *ds)
+static void vnc_dpy_switch(DisplayChangeListener *dcl,
+ DisplayState *ds,
+ DisplaySurface *surface)
{
VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs;
@@ -1981,17 +1982,6 @@ static void pixel_format_message (VncState *vs) {
vs->write_pixels = vnc_write_pixels_copy;
}
-static void vnc_dpy_setdata(DisplayChangeListener *dcl,
- DisplayState *ds)
-{
- VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
-
- qemu_pixman_image_unref(vd->guest.fb);
- vd->guest.fb = pixman_image_ref(ds->surface->image);
- vd->guest.format = ds->surface->format;
- vnc_dpy_update(dcl, ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
-}
-
static void vnc_colordepth(VncState *vs)
{
if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
@@ -2696,7 +2686,7 @@ static void vnc_init_timer(VncDisplay *vd)
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- vnc_dpy_resize(&vd->dcl, vd->ds);
+ vnc_dpy_switch(&vd->dcl, vd->ds, vd->ds->surface);
vnc_refresh(vd);
}
}
@@ -2836,8 +2826,7 @@ static const DisplayChangeListenerOps dcl_ops = {
.dpy_name = "vnc",
.dpy_gfx_copy = vnc_dpy_copy,
.dpy_gfx_update = vnc_dpy_update,
- .dpy_gfx_resize = vnc_dpy_resize,
- .dpy_gfx_setdata = vnc_dpy_setdata,
+ .dpy_gfx_switch = vnc_dpy_switch,
.dpy_mouse_set = vnc_mouse_set,
.dpy_cursor_define = vnc_dpy_cursor_define,
};
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 09/12] console: add surface_*() getters
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (7 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 08/12] console: rework DisplaySurface handling [dcl/ui side] Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 10/12] gtk: stop using DisplayState Gerd Hoffmann
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add convinence wrappers to query DisplaySurface properties.
Simliar to ds_get_*, but operating in the DisplaySurface
not the DisplayState.
With this patch in place ui frontents can stop using DisplayState
in the rendering code paths, they can simply operate using the
DisplaySurface passed in via dpy_gfx_switch callback.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 46 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index f15a541..ab59e15 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -244,36 +244,66 @@ void dpy_mouse_set(struct DisplayState *s, int x, int y, int on);
void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor);
bool dpy_cursor_define_supported(struct DisplayState *s);
+static inline int surface_stride(DisplaySurface *s)
+{
+ return pixman_image_get_stride(s->image);
+}
+
+static inline void *surface_data(DisplaySurface *s)
+{
+ return pixman_image_get_data(s->image);
+}
+
+static inline int surface_width(DisplaySurface *s)
+{
+ return pixman_image_get_width(s->image);
+}
+
+static inline int surface_height(DisplaySurface *s)
+{
+ return pixman_image_get_height(s->image);
+}
+
+static inline int surface_bits_per_pixel(DisplaySurface *s)
+{
+ int bits = PIXMAN_FORMAT_BPP(s->format);
+ return bits;
+}
+
+static inline int surface_bytes_per_pixel(DisplaySurface *s)
+{
+ int bits = PIXMAN_FORMAT_BPP(s->format);
+ return (bits + 7) / 8;
+}
+
static inline int ds_get_linesize(DisplayState *ds)
{
- return pixman_image_get_stride(ds->surface->image);
+ return surface_stride(ds->surface);
}
static inline uint8_t* ds_get_data(DisplayState *ds)
{
- return (void *)pixman_image_get_data(ds->surface->image);
+ return surface_data(ds->surface);
}
static inline int ds_get_width(DisplayState *ds)
{
- return pixman_image_get_width(ds->surface->image);
+ return surface_width(ds->surface);
}
static inline int ds_get_height(DisplayState *ds)
{
- return pixman_image_get_height(ds->surface->image);
+ return surface_height(ds->surface);
}
static inline int ds_get_bits_per_pixel(DisplayState *ds)
{
- int bits = PIXMAN_FORMAT_BPP(ds->surface->format);
- return bits;
+ return surface_bits_per_pixel(ds->surface);
}
static inline int ds_get_bytes_per_pixel(DisplayState *ds)
{
- int bits = PIXMAN_FORMAT_BPP(ds->surface->format);
- return (bits + 7) / 8;
+ return surface_bytes_per_pixel(ds->surface);
}
static inline pixman_format_code_t ds_get_format(DisplayState *ds)
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 10/12] gtk: stop using DisplayState
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (8 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 09/12] console: add surface_*() getters Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 11/12] vnc: " Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 12/12] sdl: " Gerd Hoffmann
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Rework DisplayStateListener callbacks to not use the DisplayState
any more. Factor out the window size handling to a separate function,
so the zoom callbacks can call that directly instead of abusing the
gd_switch DisplayStateListener callback for that.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/gtk.c | 140 +++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 80 insertions(+), 60 deletions(-)
diff --git a/ui/gtk.c b/ui/gtk.c
index abef1ca..f06f18e 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -143,7 +143,7 @@ typedef struct GtkDisplayState
GtkWidget *drawing_area;
cairo_surface_t *surface;
DisplayChangeListener dcl;
- DisplayState *ds;
+ DisplaySurface *ds;
int button_mask;
int last_x;
int last_y;
@@ -225,10 +225,48 @@ static void gd_update_caption(GtkDisplayState *s)
g_free(title);
}
+static void gd_update_windowsize(GtkDisplayState *s)
+{
+ if (!s->full_screen) {
+ GtkRequisition req;
+ double sx, sy;
+
+ if (s->free_scale) {
+ sx = s->scale_x;
+ sy = s->scale_y;
+
+ s->scale_y = 1.0;
+ s->scale_x = 1.0;
+ } else {
+ sx = 1.0;
+ sy = 1.0;
+ }
+
+ gtk_widget_set_size_request(s->drawing_area,
+ surface_width(s->ds) * s->scale_x,
+ surface_height(s->ds) * s->scale_y);
+#if GTK_CHECK_VERSION(3, 0, 0)
+ gtk_widget_get_preferred_size(s->vbox, NULL, &req);
+#else
+ gtk_widget_size_request(s->vbox, &req);
+#endif
+
+ gtk_window_resize(GTK_WINDOW(s->window),
+ req.width * sx, req.height * sy);
+ }
+}
+
+static void gd_update_full_redraw(GtkDisplayState *s)
+{
+ int ww, wh;
+ gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
+ gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
+}
+
/** DisplayState Callbacks **/
static void gd_update(DisplayChangeListener *dcl,
- DisplayState *ds, int x, int y, int w, int h)
+ DisplayState *dontuse, int x, int y, int w, int h)
{
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
int x1, x2, y1, y2;
@@ -244,8 +282,8 @@ static void gd_update(DisplayChangeListener *dcl,
x2 = ceil(x * s->scale_x + w * s->scale_x);
y2 = ceil(y * s->scale_y + h * s->scale_y);
- fbw = ds_get_width(s->ds) * s->scale_x;
- fbh = ds_get_height(s->ds) * s->scale_y;
+ fbw = surface_width(s->ds) * s->scale_x;
+ fbh = surface_height(s->ds) * s->scale_y;
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
@@ -261,27 +299,34 @@ static void gd_update(DisplayChangeListener *dcl,
}
static void gd_refresh(DisplayChangeListener *dcl,
- DisplayState *ds)
+ DisplayState *dontuse)
{
vga_hw_update();
}
static void gd_switch(DisplayChangeListener *dcl,
- DisplayState *ds,
+ DisplayState *dontuse,
DisplaySurface *surface)
{
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
cairo_format_t kind;
+ bool resized = true;
int stride;
DPRINTF("resize(width=%d, height=%d)\n",
- ds_get_width(ds), ds_get_height(ds));
+ surface_width(surface), surface_height(surface));
if (s->surface) {
cairo_surface_destroy(s->surface);
}
- switch (ds->surface->pf.bits_per_pixel) {
+ if (s->ds &&
+ surface_width(s->ds) == surface_width(surface) &&
+ surface_height(s->ds) == surface_height(surface)) {
+ resized = false;
+ }
+ s->ds = surface;
+ switch (surface_bits_per_pixel(surface)) {
case 8:
kind = CAIRO_FORMAT_A8;
break;
@@ -296,41 +341,19 @@ static void gd_switch(DisplayChangeListener *dcl,
break;
}
- stride = cairo_format_stride_for_width(kind, ds_get_width(ds));
- g_assert(ds_get_linesize(ds) == stride);
+ stride = cairo_format_stride_for_width(kind, surface_width(surface));
+ g_assert(surface_stride(surface) == stride);
- s->surface = cairo_image_surface_create_for_data(ds_get_data(ds),
+ s->surface = cairo_image_surface_create_for_data(surface_data(surface),
kind,
- ds_get_width(ds),
- ds_get_height(ds),
- ds_get_linesize(ds));
-
- if (!s->full_screen) {
- GtkRequisition req;
- double sx, sy;
-
- if (s->free_scale) {
- sx = s->scale_x;
- sy = s->scale_y;
-
- s->scale_y = 1.0;
- s->scale_x = 1.0;
- } else {
- sx = 1.0;
- sy = 1.0;
- }
-
- gtk_widget_set_size_request(s->drawing_area,
- ds_get_width(ds) * s->scale_x,
- ds_get_height(ds) * s->scale_y);
-#if GTK_CHECK_VERSION(3, 0, 0)
- gtk_widget_get_preferred_size(s->vbox, NULL, &req);
-#else
- gtk_widget_size_request(s->vbox, &req);
-#endif
+ surface_width(surface),
+ surface_height(surface),
+ surface_stride(surface));
- gtk_window_resize(GTK_WINDOW(s->window),
- req.width * sx, req.height * sy);
+ if (resized) {
+ gd_update_windowsize(s);
+ } else {
+ gd_update_full_redraw(s);
}
}
@@ -405,8 +428,8 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
return FALSE;
}
- fbw = ds_get_width(s->ds);
- fbh = ds_get_height(s->ds);
+ fbw = surface_width(s->ds);
+ fbh = surface_height(s->ds);
gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh);
@@ -484,8 +507,8 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
int fbh, fbw;
int ww, wh;
- fbw = ds_get_width(s->ds) * s->scale_x;
- fbh = ds_get_height(s->ds) * s->scale_y;
+ fbw = surface_width(s->ds) * s->scale_x;
+ fbh = surface_height(s->ds) * s->scale_y;
gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
@@ -501,14 +524,14 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
y = (motion->y - my) / s->scale_y;
if (x < 0 || y < 0 ||
- x >= ds_get_width(s->ds) ||
- y >= ds_get_height(s->ds)) {
+ x >= surface_width(s->ds) ||
+ y >= surface_height(s->ds)) {
return TRUE;
}
if (kbd_mouse_is_absolute()) {
- dx = x * 0x7FFF / (ds_get_width(s->ds) - 1);
- dy = y * 0x7FFF / (ds_get_height(s->ds) - 1);
+ dx = x * 0x7FFF / (surface_width(s->ds) - 1);
+ dy = y * 0x7FFF / (surface_height(s->ds) - 1);
} else if (s->last_x == -1 || s->last_y == -1) {
dx = 0;
dy = 0;
@@ -589,8 +612,8 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button,
}
if (kbd_mouse_is_absolute()) {
- dx = s->last_x * 0x7FFF / (ds_get_width(s->ds) - 1);
- dy = s->last_y * 0x7FFF / (ds_get_height(s->ds) - 1);
+ dx = s->last_x * 0x7FFF / (surface_width(s->ds) - 1);
+ dy = s->last_y * 0x7FFF / (surface_height(s->ds) - 1);
} else {
dx = 0;
dy = 0;
@@ -719,7 +742,8 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
gd_menu_show_tabs(GTK_MENU_ITEM(s->show_tabs_item), s);
gtk_widget_set_size_request(s->menu_bar, -1, -1);
gtk_widget_set_size_request(s->drawing_area,
- ds_get_width(s->ds), ds_get_height(s->ds));
+ surface_width(s->ds),
+ surface_height(s->ds));
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE);
s->full_screen = FALSE;
s->scale_x = 1.0;
@@ -739,7 +763,7 @@ static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
s->scale_x += .25;
s->scale_y += .25;
- gd_switch(&s->dcl, s->ds, s->ds->surface);
+ gd_update_windowsize(s);
}
static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
@@ -755,7 +779,7 @@ static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
s->scale_x = MAX(s->scale_x, .25);
s->scale_y = MAX(s->scale_y, .25);
- gd_switch(&s->dcl, s->ds, s->ds->surface);
+ gd_update_windowsize(s);
}
static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
@@ -765,13 +789,12 @@ static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
s->scale_x = 1.0;
s->scale_y = 1.0;
- gd_switch(&s->dcl, s->ds, s->ds->surface);
+ gd_update_windowsize(s);
}
static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
{
GtkDisplayState *s = opaque;
- int ww, wh;
if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item))) {
s->free_scale = TRUE;
@@ -779,10 +802,8 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
s->free_scale = FALSE;
}
- gd_switch(&s->dcl, s->ds, s->ds->surface);
-
- gdk_drawable_get_size(gtk_widget_get_window(s->drawing_area), &ww, &wh);
- gtk_widget_queue_draw_area(s->drawing_area, 0, 0, ww, wh);
+ gd_update_windowsize(s);
+ gd_update_full_redraw(s);
}
static void gd_grab_keyboard(GtkDisplayState *s)
@@ -1298,7 +1319,6 @@ void gtk_display_init(DisplayState *ds)
gtk_init(NULL, NULL);
- s->ds = ds;
s->dcl.ops = &dcl_ops;
s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 11/12] vnc: stop using DisplayState
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (9 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 10/12] gtk: stop using DisplayState Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 12/12] sdl: " Gerd Hoffmann
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Rework DisplayStateListener callbacks to not use the DisplayState
any more.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/vnc-enc-tight.c | 7 ++---
ui/vnc-jobs.c | 1 -
ui/vnc.c | 73 +++++++++++++++++++++++++++++-----------------------
ui/vnc.h | 3 +--
4 files changed, 46 insertions(+), 38 deletions(-)
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 4ddea7d..e6966ae 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -123,7 +123,7 @@ static bool tight_can_send_png_rect(VncState *vs, int w, int h)
return false;
}
- if (ds_get_bytes_per_pixel(vs->ds) == 1 ||
+ if (surface_bytes_per_pixel(vs->vd->ds) == 1 ||
vs->client_pf.bytes_per_pixel == 1) {
return false;
}
@@ -301,7 +301,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
return 0;
}
- if (ds_get_bytes_per_pixel(vs->ds) == 1 ||
+ if (surface_bytes_per_pixel(vs->vd->ds) == 1 ||
vs->client_pf.bytes_per_pixel == 1 ||
w < VNC_TIGHT_DETECT_MIN_WIDTH || h < VNC_TIGHT_DETECT_MIN_HEIGHT) {
return 0;
@@ -1184,8 +1184,9 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
uint8_t *buf;
int dy;
- if (ds_get_bytes_per_pixel(vs->ds) == 1)
+ if (surface_bytes_per_pixel(vs->vd->ds) == 1) {
return send_full_color_rect(vs, x, y, w, h);
+ }
buffer_reserve(&vs->tight.jpeg, 2048);
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
index 0bfc0c5..2d3fce8 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -183,7 +183,6 @@ static void vnc_async_encoding_start(VncState *orig, VncState *local)
{
local->vnc_encoding = orig->vnc_encoding;
local->features = orig->features;
- local->ds = orig->ds;
local->vd = orig->vd;
local->lossy_rect = orig->lossy_rect;
local->write_pixels = orig->write_pixels;
diff --git a/ui/vnc.c b/ui/vnc.c
index f8398c3..ea6f37c 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -519,17 +519,17 @@ void buffer_advance(Buffer *buf, size_t len)
static void vnc_desktop_resize(VncState *vs)
{
- DisplayState *ds = vs->ds;
+ DisplaySurface *ds = vs->vd->ds;
if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
return;
}
- if (vs->client_width == ds_get_width(ds) &&
- vs->client_height == ds_get_height(ds)) {
+ if (vs->client_width == surface_width(ds) &&
+ vs->client_height == surface_height(ds)) {
return;
}
- vs->client_width = ds_get_width(ds);
- vs->client_height = ds_get_height(ds);
+ vs->client_width = surface_width(ds);
+ vs->client_height = surface_height(ds);
vnc_lock_output(vs);
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
@@ -575,7 +575,7 @@ void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
}
static void vnc_dpy_switch(DisplayChangeListener *dcl,
- DisplayState *ds,
+ DisplayState *dontuse,
DisplaySurface *surface)
{
VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
@@ -585,9 +585,10 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
/* server surface */
qemu_pixman_image_unref(vd->server);
+ vd->ds = surface;
vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
- ds_get_width(ds),
- ds_get_height(ds),
+ surface_width(vd->ds),
+ surface_height(vd->ds),
NULL, 0);
/* guest surface */
@@ -596,8 +597,8 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
console_color_init(ds);
#endif
qemu_pixman_image_unref(vd->guest.fb);
- vd->guest.fb = pixman_image_ref(ds->surface->image);
- vd->guest.format = ds->surface->format;
+ vd->guest.fb = pixman_image_ref(surface->image);
+ vd->guest.format = surface->format;
memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty));
QTAILQ_FOREACH(vs, &vd->clients, next) {
@@ -739,7 +740,7 @@ static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, i
}
static void vnc_dpy_copy(DisplayChangeListener *dcl,
- DisplayState *ds,
+ DisplayState *dontuse,
int src_x, int src_y,
int dst_x, int dst_y, int w, int h)
{
@@ -813,7 +814,7 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl,
}
static void vnc_mouse_set(DisplayChangeListener *dcl,
- DisplayState *ds,
+ DisplayState *dontuse,
int x, int y, int visible)
{
/* can we ask the client(s) to move the pointer ??? */
@@ -841,7 +842,7 @@ static int vnc_cursor_define(VncState *vs)
}
static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
- DisplayState *ds,
+ DisplayState *dontuse,
QEMUCursor *c)
{
VncDisplay *vd = vnc_display;
@@ -1463,7 +1464,8 @@ static void check_pointer_type_change(Notifier *notifier, void *data)
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
vnc_framebuffer_update(vs, absolute, 0,
- ds_get_width(vs->ds), ds_get_height(vs->ds),
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
VNC_ENCODING_POINTER_TYPE_CHANGE);
vnc_unlock_output(vs);
vnc_flush(vs);
@@ -1475,6 +1477,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
{
int buttons = 0;
int dz = 0;
+ int width = surface_width(vs->vd->ds);
+ int height = surface_height(vs->vd->ds);
if (button_mask & 0x01)
buttons |= MOUSE_EVENT_LBUTTON;
@@ -1488,10 +1492,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
dz = 1;
if (vs->absolute) {
- kbd_mouse_event(ds_get_width(vs->ds) > 1 ?
- x * 0x7FFF / (ds_get_width(vs->ds) - 1) : 0x4000,
- ds_get_height(vs->ds) > 1 ?
- y * 0x7FFF / (ds_get_height(vs->ds) - 1) : 0x4000,
+ kbd_mouse_event(width > 1 ? x * 0x7FFF / (width - 1) : 0x4000,
+ height > 1 ? y * 0x7FFF / (height - 1) : 0x4000,
dz, buttons);
} else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
x -= 0x7FFF;
@@ -1781,12 +1783,15 @@ static void framebuffer_update_request(VncState *vs, int incremental,
int w, int h)
{
int i;
- const size_t width = ds_get_width(vs->ds) / 16;
+ const size_t width = surface_width(vs->vd->ds) / 16;
+ const size_t height = surface_height(vs->vd->ds);
- if (y_position > ds_get_height(vs->ds))
- y_position = ds_get_height(vs->ds);
- if (y_position + h >= ds_get_height(vs->ds))
- h = ds_get_height(vs->ds) - y_position;
+ if (y_position > height) {
+ y_position = height;
+ }
+ if (y_position + h >= height) {
+ h = height - y_position;
+ }
vs->need_update = 1;
if (!incremental) {
@@ -1805,7 +1810,9 @@ static void send_ext_key_event_ack(VncState *vs)
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
+ vnc_framebuffer_update(vs, 0, 0,
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
VNC_ENCODING_EXT_KEY_EVENT);
vnc_unlock_output(vs);
vnc_flush(vs);
@@ -1817,7 +1824,9 @@ static void send_ext_audio_ack(VncState *vs)
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds),
+ vnc_framebuffer_update(vs, 0, 0,
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
VNC_ENCODING_AUDIO);
vnc_unlock_output(vs);
vnc_flush(vs);
@@ -1990,8 +1999,10 @@ static void vnc_colordepth(VncState *vs)
vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
vnc_write_u8(vs, 0);
vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds),
- ds_get_height(vs->ds), VNC_ENCODING_WMVi);
+ vnc_framebuffer_update(vs, 0, 0,
+ surface_width(vs->vd->ds),
+ surface_height(vs->vd->ds),
+ VNC_ENCODING_WMVi);
pixel_format_message(vs);
vnc_unlock_output(vs);
vnc_flush(vs);
@@ -2207,8 +2218,8 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
}
vnc_set_share_mode(vs, mode);
- vs->client_width = ds_get_width(vs->ds);
- vs->client_height = ds_get_height(vs->ds);
+ vs->client_width = surface_width(vs->vd->ds);
+ vs->client_height = surface_height(vs->vd->ds);
vnc_write_u16(vs, vs->client_width);
vnc_write_u16(vs, vs->client_height);
@@ -2686,7 +2697,7 @@ static void vnc_init_timer(VncDisplay *vd)
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- vnc_dpy_switch(&vd->dcl, vd->ds, vd->ds->surface);
+ vga_hw_update();
vnc_refresh(vd);
}
}
@@ -2756,7 +2767,6 @@ void vnc_init_state(VncState *vs)
vs->initialized = true;
VncDisplay *vd = vs->vd;
- vs->ds = vd->ds;
vs->last_x = -1;
vs->last_y = -1;
@@ -2843,7 +2853,6 @@ void vnc_display_init(DisplayState *ds)
vs->lwebsock = -1;
#endif
- vs->ds = ds;
QTAILQ_INIT(&vs->clients);
vs->expires = TIME_MAX;
diff --git a/ui/vnc.h b/ui/vnc.h
index a96485b..58e002e 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -150,7 +150,7 @@ struct VncDisplay
bool websocket;
char *ws_display;
#endif
- DisplayState *ds;
+ DisplaySurface *ds;
DisplayChangeListener dcl;
kbd_layout_t *kbd_layout;
int lock_key_sync;
@@ -248,7 +248,6 @@ struct VncState
{
int csock;
- DisplayState *ds;
DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
* vnc-jobs-async.c */
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [RfC PATCH 12/12] sdl: stop using DisplayState
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
` (10 preceding siblings ...)
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 11/12] vnc: " Gerd Hoffmann
@ 2013-03-01 9:00 ` Gerd Hoffmann
11 siblings, 0 replies; 13+ messages in thread
From: Gerd Hoffmann @ 2013-03-01 9:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Rework DisplayStateListener callbacks to not use the DisplayState
any more.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/sdl.c | 92 ++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 51 insertions(+), 41 deletions(-)
diff --git a/ui/sdl.c b/ui/sdl.c
index 85eefdf..58f16bc 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -35,6 +35,7 @@
#include "sdl_zoom.h"
static DisplayChangeListener *dcl;
+static DisplaySurface *surface;
static SDL_Surface *real_screen;
static SDL_Surface *guest_screen = NULL;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
@@ -60,7 +61,7 @@ static int scaling_active = 0;
static Notifier mouse_mode_notifier;
static void sdl_update(DisplayChangeListener *dcl,
- DisplayState *ds,
+ DisplayState *dontuse,
int x, int y, int w, int h)
{
// printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
@@ -83,17 +84,6 @@ static void sdl_update(DisplayChangeListener *dcl,
SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
}
-static void sdl_setdata(DisplayChangeListener *dcl,
- DisplayState *ds)
-{
- 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 do_sdl_resize(int width, int height, int bpp)
{
int flags;
@@ -118,16 +108,32 @@ static void do_sdl_resize(int width, int height, int bpp)
}
static void sdl_switch(DisplayChangeListener *dcl,
- DisplayState *ds,
- DisplaySurface *surface)
+ DisplayState *dontuse,
+ DisplaySurface *new_surface)
{
+
+ /* temporary hack: allows to call sdl_switch to handle scaling changes */
+ if (new_surface) {
+ surface = new_surface;
+ }
+
if (!scaling_active) {
- do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
- } else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) {
+ do_sdl_resize(surface_width(surface), surface_height(surface), 0);
+ } else if (real_screen->format->BitsPerPixel !=
+ surface_bits_per_pixel(surface)) {
do_sdl_resize(real_screen->w, real_screen->h,
- ds_get_bits_per_pixel(ds));
+ surface_bits_per_pixel(surface));
}
- sdl_setdata(dcl, ds);
+
+ if (guest_screen != NULL) {
+ SDL_FreeSurface(guest_screen);
+ }
+ guest_screen = SDL_CreateRGBSurfaceFrom
+ (surface_data(surface),
+ surface_width(surface), surface_height(surface),
+ surface_bits_per_pixel(surface), surface_stride(surface),
+ surface->pf.rmask, surface->pf.gmask,
+ surface->pf.bmask, surface->pf.amask);
}
/* generic keyboard conversion */
@@ -450,7 +456,7 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
kbd_mouse_event(dx, dy, dz, buttons);
}
-static void sdl_scale(DisplayState *ds, int width, int height)
+static void sdl_scale(int width, int height)
{
int bpp = real_screen->format->BitsPerPixel;
@@ -461,25 +467,28 @@ static void sdl_scale(DisplayState *ds, int width, int height)
scaling_active = 1;
}
-static void toggle_full_screen(DisplayState *ds)
+static void toggle_full_screen(void)
{
+ int width = surface_width(surface);
+ int height = surface_height(surface);
+ int bpp = surface_bits_per_pixel(surface);
+
gui_fullscreen = !gui_fullscreen;
if (gui_fullscreen) {
gui_saved_width = real_screen->w;
gui_saved_height = real_screen->h;
gui_saved_scaling = scaling_active;
- do_sdl_resize(ds_get_width(ds), ds_get_height(ds),
- ds_get_bits_per_pixel(ds));
+ do_sdl_resize(width, height, bpp);
scaling_active = 0;
gui_saved_grab = gui_grab;
sdl_grab_start();
} else {
if (gui_saved_scaling) {
- sdl_scale(ds, gui_saved_width, gui_saved_height);
+ sdl_scale(gui_saved_width, gui_saved_height);
} else {
- do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
+ do_sdl_resize(width, height, 0);
}
if (!gui_saved_grab || !is_graphic_console()) {
sdl_grab_end();
@@ -489,7 +498,7 @@ static void toggle_full_screen(DisplayState *ds)
vga_hw_update();
}
-static void handle_keydown(DisplayState *ds, SDL_Event *ev)
+static void handle_keydown(SDL_Event *ev)
{
int mod_state;
int keycode;
@@ -508,13 +517,13 @@ static void handle_keydown(DisplayState *ds, SDL_Event *ev)
keycode = sdl_keyevent_to_keycode(&ev->key);
switch (keycode) {
case 0x21: /* 'f' key on US keyboard */
- toggle_full_screen(ds);
+ toggle_full_screen();
gui_keysym = 1;
break;
case 0x16: /* 'u' key on US keyboard */
if (scaling_active) {
scaling_active = 0;
- sdl_switch(dcl, ds, ds->surface);
+ sdl_switch(dcl, NULL, NULL);
vga_hw_invalidate();
vga_hw_update();
}
@@ -545,9 +554,10 @@ static void handle_keydown(DisplayState *ds, SDL_Event *ev)
if (!gui_fullscreen) {
int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50),
160);
- int height = (ds_get_height(ds) * width) / ds_get_width(ds);
+ int height = (surface_height(surface) * width) /
+ surface_width(surface);
- sdl_scale(ds, width, height);
+ sdl_scale(width, height);
vga_hw_invalidate();
vga_hw_update();
gui_keysym = 1;
@@ -634,7 +644,7 @@ static void handle_keydown(DisplayState *ds, SDL_Event *ev)
}
}
-static void handle_keyup(DisplayState *ds, SDL_Event *ev)
+static void handle_keyup(SDL_Event *ev)
{
int mod_state;
@@ -666,7 +676,7 @@ static void handle_keyup(DisplayState *ds, SDL_Event *ev)
}
}
-static void handle_mousemotion(DisplayState *ds, SDL_Event *ev)
+static void handle_mousemotion(SDL_Event *ev)
{
int max_x, max_y;
@@ -690,7 +700,7 @@ static void handle_mousemotion(DisplayState *ds, SDL_Event *ev)
}
}
-static void handle_mousebutton(DisplayState *ds, SDL_Event *ev)
+static void handle_mousebutton(SDL_Event *ev)
{
int buttonstate = SDL_GetMouseState(NULL, NULL);
SDL_MouseButtonEvent *bev;
@@ -726,7 +736,7 @@ static void handle_mousebutton(DisplayState *ds, SDL_Event *ev)
}
}
-static void handle_activation(DisplayState *ds, SDL_Event *ev)
+static void handle_activation(SDL_Event *ev)
{
#ifdef _WIN32
/* Disable grab if the window no longer has the focus
@@ -754,7 +764,7 @@ static void handle_activation(DisplayState *ds, SDL_Event *ev)
}
static void sdl_refresh(DisplayChangeListener *dcl,
- DisplayState *ds)
+ DisplayState *dontuse)
{
SDL_Event ev1, *ev = &ev1;
@@ -769,13 +779,13 @@ static void sdl_refresh(DisplayChangeListener *dcl,
while (SDL_PollEvent(ev)) {
switch (ev->type) {
case SDL_VIDEOEXPOSE:
- sdl_update(dcl, ds, 0, 0, real_screen->w, real_screen->h);
+ sdl_update(dcl, dontuse, 0, 0, real_screen->w, real_screen->h);
break;
case SDL_KEYDOWN:
- handle_keydown(ds, ev);
+ handle_keydown(ev);
break;
case SDL_KEYUP:
- handle_keyup(ds, ev);
+ handle_keyup(ev);
break;
case SDL_QUIT:
if (!no_quit) {
@@ -784,17 +794,17 @@ static void sdl_refresh(DisplayChangeListener *dcl,
}
break;
case SDL_MOUSEMOTION:
- handle_mousemotion(ds, ev);
+ handle_mousemotion(ev);
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
- handle_mousebutton(ds, ev);
+ handle_mousebutton(ev);
break;
case SDL_ACTIVEEVENT:
- handle_activation(ds, ev);
+ handle_activation(ev);
break;
case SDL_VIDEORESIZE:
- sdl_scale(ds, ev->resize.w, ev->resize.h);
+ sdl_scale(ev->resize.w, ev->resize.h);
vga_hw_invalidate();
vga_hw_update();
break;
--
1.7.9.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-03-01 9:01 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-01 9:00 [Qemu-devel] [RfC PATCH 00/12] console/display: cleanup & untangle data structures Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 01/12] console: fix displaychangelisteners interface Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 02/12] console: kill DisplayState->opaque Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 03/12] spice: zap sdpy global Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 04/12] qxl: zap qxl0 global Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 05/12] qxl: better vga init in enter_vga_mode Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 06/12] sdl: drop dead code Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 07/12] console: rework DisplaySurface handling [vga emu side] Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 08/12] console: rework DisplaySurface handling [dcl/ui side] Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 09/12] console: add surface_*() getters Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 10/12] gtk: stop using DisplayState Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 11/12] vnc: " Gerd Hoffmann
2013-03-01 9:00 ` [Qemu-devel] [RfC PATCH 12/12] sdl: " Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).