console: give each QemuConsole its own DisplaySurface

Go away from the global DisplaySurface, give one to each QemuConsole
instead.  With this patch applied it is possible to call
graphics_hw_* functions with qemu consoles which are not the current
foreground console.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2013-03-12 14:39:22 +01:00
parent 1dbfa00503
commit 321f048d24
2 changed files with 70 additions and 29 deletions

View File

@ -183,7 +183,6 @@ struct DisplayChangeListener {
}; };
struct DisplayState { struct DisplayState {
struct DisplaySurface *surface;
struct QEMUTimer *gui_timer; struct QEMUTimer *gui_timer;
bool have_gfx; bool have_gfx;
bool have_text; bool have_text;

View File

@ -116,6 +116,7 @@ struct QemuConsole {
int index; int index;
console_type_t console_type; console_type_t console_type;
DisplayState *ds; DisplayState *ds;
DisplaySurface *surface;
/* Graphic console state. */ /* Graphic console state. */
graphic_hw_update_ptr hw_update; graphic_hw_update_ptr hw_update;
@ -164,6 +165,8 @@ static QemuConsole *consoles[MAX_CONSOLES];
static int nb_consoles = 0; static int nb_consoles = 0;
static void text_console_do_init(CharDriverState *chr, DisplayState *ds); static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
static void dpy_gfx_switch_surface(DisplayState *ds,
DisplaySurface *surface);
void graphic_hw_update(QemuConsole *con) void graphic_hw_update(QemuConsole *con)
{ {
@ -933,8 +936,9 @@ void console_select(unsigned int index)
} }
active_console = s; active_console = s;
if (ds->have_gfx) { if (ds->have_gfx) {
surface = qemu_create_displaysurface(s->g_width, s->g_height); dpy_gfx_switch_surface(ds, s->surface);
dpy_gfx_replace_surface(s, surface); dpy_gfx_update(s, 0, 0, surface_width(s->surface),
surface_height(s->surface));
} }
if (ds->have_text) { if (ds->have_text) {
dpy_text_resize(s, s->width, s->height); dpy_text_resize(s, s->width, s->height);
@ -943,7 +947,6 @@ void console_select(unsigned int index)
qemu_mod_timer(s->cursor_timer, qemu_mod_timer(s->cursor_timer,
qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2); qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
} }
graphic_hw_invalidate(s);
} }
} }
@ -1195,8 +1198,8 @@ void register_displaychangelistener(DisplayState *ds,
dcl->ds = ds; dcl->ds = ds;
QLIST_INSERT_HEAD(&ds->listeners, dcl, next); QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
gui_setup_refresh(ds); gui_setup_refresh(ds);
if (dcl->ops->dpy_gfx_switch) { if (dcl->ops->dpy_gfx_switch && active_console) {
dcl->ops->dpy_gfx_switch(dcl, ds->surface); dcl->ops->dpy_gfx_switch(dcl, active_console->surface);
} }
} }
@ -1212,8 +1215,8 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
int width = pixman_image_get_width(s->surface->image); int width = surface_width(con->surface);
int height = pixman_image_get_height(s->surface->image); int height = surface_height(con->surface);
x = MAX(x, 0); x = MAX(x, 0);
y = MAX(y, 0); y = MAX(y, 0);
@ -1222,6 +1225,9 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
w = MIN(w, width - x); w = MIN(w, width - x);
h = MIN(h, height - y); h = MIN(h, height - y);
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_gfx_update) { if (dcl->ops->dpy_gfx_update) {
dcl->ops->dpy_gfx_update(dcl, x, y, w, h); dcl->ops->dpy_gfx_update(dcl, x, y, w, h);
@ -1229,18 +1235,27 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
} }
} }
static void dpy_gfx_switch_surface(DisplayState *ds,
DisplaySurface *surface)
{
struct DisplayChangeListener *dcl;
QLIST_FOREACH(dcl, &ds->listeners, next) {
if (dcl->ops->dpy_gfx_switch) {
dcl->ops->dpy_gfx_switch(dcl, surface);
}
}
}
void dpy_gfx_replace_surface(QemuConsole *con, void dpy_gfx_replace_surface(QemuConsole *con,
DisplaySurface *surface) DisplaySurface *surface)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
DisplaySurface *old_surface = s->surface; DisplaySurface *old_surface = con->surface;
struct DisplayChangeListener *dcl;
s->surface = surface; con->surface = surface;
QLIST_FOREACH(dcl, &s->listeners, next) { if (con == active_console) {
if (dcl->ops->dpy_gfx_switch) { dpy_gfx_switch_surface(s, surface);
dcl->ops->dpy_gfx_switch(dcl, surface);
}
} }
qemu_free_displaysurface(old_surface); qemu_free_displaysurface(old_surface);
} }
@ -1260,6 +1275,10 @@ void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_gfx_copy) { if (dcl->ops->dpy_gfx_copy) {
dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h); dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h);
@ -1273,6 +1292,10 @@ void dpy_text_cursor(QemuConsole *con, int x, int y)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_text_cursor) { if (dcl->ops->dpy_text_cursor) {
dcl->ops->dpy_text_cursor(dcl, x, y); dcl->ops->dpy_text_cursor(dcl, x, y);
@ -1284,6 +1307,10 @@ void dpy_text_update(QemuConsole *con, int x, int y, int w, int h)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_text_update) { if (dcl->ops->dpy_text_update) {
dcl->ops->dpy_text_update(dcl, x, y, w, h); dcl->ops->dpy_text_update(dcl, x, y, w, h);
@ -1295,6 +1322,10 @@ void dpy_text_resize(QemuConsole *con, int w, int h)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_text_resize) { if (dcl->ops->dpy_text_resize) {
dcl->ops->dpy_text_resize(dcl, w, h); dcl->ops->dpy_text_resize(dcl, w, h);
@ -1306,6 +1337,10 @@ void dpy_mouse_set(QemuConsole *con, int x, int y, int on)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_mouse_set) { if (dcl->ops->dpy_mouse_set) {
dcl->ops->dpy_mouse_set(dcl, x, y, on); dcl->ops->dpy_mouse_set(dcl, x, y, on);
@ -1317,6 +1352,10 @@ void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor)
{ {
DisplayState *s = con->ds; DisplayState *s = con->ds;
struct DisplayChangeListener *dcl; struct DisplayChangeListener *dcl;
if (con != active_console) {
return;
}
QLIST_FOREACH(dcl, &s->listeners, next) { QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_cursor_define) { if (dcl->ops->dpy_cursor_define) {
dcl->ops->dpy_cursor_define(dcl, cursor); dcl->ops->dpy_cursor_define(dcl, cursor);
@ -1390,9 +1429,7 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
s->hw_text_update = text_update; s->hw_text_update = text_update;
s->hw = opaque; s->hw = opaque;
if (!ds->surface) { s->surface = qemu_create_displaysurface(width, height);
ds->surface = qemu_create_displaysurface(width, height);
}
return s; return s;
} }
@ -1442,9 +1479,15 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->x = 0; s->x = 0;
s->y = 0; s->y = 0;
if (s->console_type == TEXT_CONSOLE) { if (s->console_type == TEXT_CONSOLE) {
s->g_width = surface_width(s->ds->surface); if (active_console && active_console->surface) {
s->g_height = surface_height(s->ds->surface); s->g_width = surface_width(active_console->surface);
s->g_height = surface_height(active_console->surface);
} else {
s->g_width = 80 * FONT_WIDTH;
s->g_height = 24 * FONT_HEIGHT;
}
} }
s->surface = qemu_create_displaysurface(s->g_width, s->g_height);
s->cursor_timer = s->cursor_timer =
qemu_new_timer_ms(rt_clock, text_console_update_cursor, s); qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
@ -1539,26 +1582,25 @@ void register_vc_handler(VcHandler *handler)
void qemu_console_resize(QemuConsole *s, int width, int height) void qemu_console_resize(QemuConsole *s, int width, int height)
{ {
DisplaySurface *surface;
assert(s->console_type == GRAPHIC_CONSOLE);
s->g_width = width; s->g_width = width;
s->g_height = height; s->g_height = height;
if (is_graphic_console()) { surface = qemu_create_displaysurface(width, height);
DisplaySurface *surface; dpy_gfx_replace_surface(s, surface);
surface = qemu_create_displaysurface(width, height);
dpy_gfx_replace_surface(s, surface);
}
} }
void qemu_console_copy(QemuConsole *con, int src_x, int src_y, void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
int dst_x, int dst_y, int w, int h) int dst_x, int dst_y, int w, int h)
{ {
if (is_graphic_console()) { assert(con->console_type == GRAPHIC_CONSOLE);
dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h); dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h);
}
} }
DisplaySurface *qemu_console_surface(QemuConsole *console) DisplaySurface *qemu_console_surface(QemuConsole *console)
{ {
return console->ds->surface; return console->surface;
} }
DisplayState *qemu_console_displaystate(QemuConsole *console) DisplayState *qemu_console_displaystate(QemuConsole *console)