From patchwork Fri Mar 1 09:00:32 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 224259 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C62732C029D for ; Fri, 1 Mar 2013 20:04:54 +1100 (EST) Received: from localhost ([::1]:55119 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UBLtc-0001c7-SD for incoming@patchwork.ozlabs.org; Fri, 01 Mar 2013 04:04:52 -0500 Received: from eggs.gnu.org ([208.118.235.92]:43605) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UBLpl-0003p4-QJ for qemu-devel@nongnu.org; Fri, 01 Mar 2013 04:01:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UBLpg-00031A-9u for qemu-devel@nongnu.org; Fri, 01 Mar 2013 04:00:53 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50601) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UBLpf-00030Y-A9 for qemu-devel@nongnu.org; Fri, 01 Mar 2013 04:00:47 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2190k7x009246 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 1 Mar 2013 04:00:46 -0500 Received: from rincewind.home.kraxel.org (ovpn-116-72.ams2.redhat.com [10.36.116.72]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r2190iLi007835; Fri, 1 Mar 2013 04:00:44 -0500 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id 8A4054044F; Fri, 1 Mar 2013 10:00:43 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 1 Mar 2013 10:00:32 +0100 Message-Id: <1362128443-15687-2-git-send-email-kraxel@redhat.com> In-Reply-To: <1362128443-15687-1-git-send-email-kraxel@redhat.com> References: <1362128443-15687-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: =?UTF-8?q?Andreas=20F=C3=A4rber?= , Gerd Hoffmann , Anthony Liguori Subject: [Qemu-devel] [RfC PATCH 01/12] console: fix displaychangelisteners interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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; } }