qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/8] console cleanups
@ 2012-10-15  9:51 Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 1/8] console: QLIST-ify display change listeners Gerd Hoffmann
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

First step in making qemu use pixman:  A bunch of console subsystem
cleanups.

cheers,
  Gerd

The following changes since commit 8b4a3df8081f3e6f1061ed5cbb303ad623ade66b:

  Fix popcnt in long mode (2012-10-14 14:55:09 +0400)

are available in the git repository at:
  git://git.kraxel.org/qemu pixman.v2

Gerd Hoffmann (8):
      console: QLIST-ify display change listeners.
      console: add unregister_displaychangelistener
      console: move set_mouse + cursor_define callbacks
      console: s/TextConsole/QemuConsole/
      console: untangle gfx & txt updates
      console: init displaychangelisteners on register
      vga: fix text mode updating
      console: remove dpy_gfx_fill

 console.c            |  133 ++++++++++++++++++++-------------------
 console.h            |  171 ++++++++++++++++++++++++++++++++++---------------
 hw/blizzard.c        |    4 +-
 hw/exynos4210_fimd.c |    2 +-
 hw/g364fb.c          |    7 +-
 hw/jazz_led.c        |    6 +-
 hw/milkymist-vgafb.c |    2 +-
 hw/musicpal.c        |    2 +-
 hw/nseries.c         |    2 +-
 hw/omap_lcdc.c       |    2 +-
 hw/palm.c            |    2 +-
 hw/pl110.c           |    2 +-
 hw/pxa2xx_lcd.c      |    8 +-
 hw/qxl-render.c      |   12 ++--
 hw/qxl.c             |    4 +-
 hw/sm501.c           |    4 +-
 hw/ssd0303.c         |    2 +-
 hw/ssd0323.c         |    2 +-
 hw/tc6393xb.c        |    4 +-
 hw/tcx.c             |   16 +++---
 hw/vga.c             |   63 +++++++++++-------
 hw/vga_int.h         |    2 +
 hw/vmware_vga.c      |   15 +++--
 hw/xenfb.c           |    2 +-
 qemu-common.h        |    3 +-
 ui/curses.c          |   21 ++----
 ui/sdl.c             |   25 +++-----
 ui/spice-display.c   |    8 +-
 ui/vnc.c             |   16 +++---
 vl.c                 |   49 ++++++++++----
 30 files changed, 342 insertions(+), 249 deletions(-)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 1/8] console: QLIST-ify display change listeners.
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener Gerd Hoffmann
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h  |   72 +++++++++++++++++++++++++++++++----------------------------
 hw/xenfb.c |    2 +-
 vl.c       |    9 ++-----
 3 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/console.h b/console.h
index f990684..646ad4b 100644
--- a/console.h
+++ b/console.h
@@ -164,7 +164,7 @@ struct DisplayChangeListener {
                      int w, int h, uint32_t c);
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
-    struct DisplayChangeListener *next;
+    QLIST_ENTRY(DisplayChangeListener) next;
 };
 
 struct DisplayAllocator {
@@ -179,7 +179,7 @@ struct DisplayState {
     struct QEMUTimer *gui_timer;
 
     struct DisplayAllocator* allocator;
-    struct DisplayChangeListener* listeners;
+    QLIST_HEAD(, DisplayChangeListener) listeners;
 
     void (*mouse_set)(int x, int y, int on);
     void (*cursor_define)(QEMUCursor *cursor);
@@ -231,72 +231,76 @@ static inline int is_buffer_shared(DisplaySurface *surface)
 
 static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
 {
-    dcl->next = ds->listeners;
-    ds->listeners = dcl;
+    QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
 }
 
 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
         dcl->dpy_update(s, x, y, w, h);
-        dcl = dcl->next;
     }
 }
 
 static inline void dpy_resize(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
         dcl->dpy_resize(s);
-        dcl = dcl->next;
     }
 }
 
 static inline void dpy_setdata(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_setdata) dcl->dpy_setdata(s);
-        dcl = dcl->next;
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_setdata) {
+            dcl->dpy_setdata(s);
+        }
     }
 }
 
 static inline void dpy_refresh(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_refresh) dcl->dpy_refresh(s);
-        dcl = dcl->next;
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_refresh) {
+            dcl->dpy_refresh(s);
+        }
     }
 }
 
 static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
-                             int dst_x, int dst_y, int w, int h) {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_copy)
+                             int dst_x, int dst_y, int w, int h)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_copy) {
             dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
-        else /* TODO */
+        } else { /* TODO */
             dcl->dpy_update(s, dst_x, dst_y, w, h);
-        dcl = dcl->next;
+        }
     }
 }
 
 static inline void dpy_fill(struct DisplayState *s, int x, int y,
-                             int w, int h, uint32_t c) {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_fill) dcl->dpy_fill(s, x, y, w, h, c);
-        dcl = dcl->next;
+                             int w, int h, uint32_t c)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_fill) {
+            dcl->dpy_fill(s, x, y, w, h, c);
+        }
     }
 }
 
-static inline void dpy_cursor(struct DisplayState *s, int x, int y) {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_text_cursor) dcl->dpy_text_cursor(s, x, y);
-        dcl = dcl->next;
+static inline void dpy_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);
+        }
     }
 }
 
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 338800a..ef24c33 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -717,7 +717,7 @@ static void xenfb_update(void *opaque)
 	if (xenfb_queue_full(xenfb))
 	    return;
 
-        for (l = xenfb->c.ds->listeners; l != NULL; l = l->next) {
+        QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
             if (l->idle)
                 continue;
             idle = 0;
diff --git a/vl.c b/vl.c
index 5b357a3..23743af 100644
--- a/vl.c
+++ b/vl.c
@@ -1275,15 +1275,14 @@ static void gui_update(void *opaque)
 {
     uint64_t interval = GUI_REFRESH_INTERVAL;
     DisplayState *ds = opaque;
-    DisplayChangeListener *dcl = ds->listeners;
+    DisplayChangeListener *dcl;
 
     dpy_refresh(ds);
 
-    while (dcl != NULL) {
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
         if (dcl->gui_timer_interval &&
             dcl->gui_timer_interval < interval)
             interval = dcl->gui_timer_interval;
-        dcl = dcl->next;
     }
     qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
 }
@@ -3726,14 +3725,12 @@ int main(int argc, char **argv, char **envp)
 
     /* display setup */
     dpy_resize(ds);
-    dcl = ds->listeners;
-    while (dcl != NULL) {
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
         if (dcl->dpy_refresh != NULL) {
             ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
             qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
             break;
         }
-        dcl = dcl->next;
     }
     text_consoles_set_display(ds);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 1/8] console: QLIST-ify display change listeners Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15 14:16   ` Andreas Färber
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 3/8] console: move set_mouse + cursor_define callbacks Gerd Hoffmann
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Also change the way the gui_timer is initialized: each time a
displaychangelistener is registered or unregistered we'll check
whenever we need a timer (due to dpy_refresh callback being present)
and if so setup a timer, otherwise zap it.  This way the gui timer works
correctly with displaychangelisteners coming and going.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h |   10 ++++++++++
 vl.c      |   31 +++++++++++++++++++++++--------
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/console.h b/console.h
index 646ad4b..48fef22 100644
--- a/console.h
+++ b/console.h
@@ -229,9 +229,19 @@ static inline int is_buffer_shared(DisplaySurface *surface)
             !(surface->flags & QEMU_REALPIXELS_FLAG));
 }
 
+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);
+}
+
+static inline void unregister_displaychangelistener(DisplayState *ds,
+                                                    DisplayChangeListener *dcl)
+{
+    QLIST_REMOVE(dcl, next);
+    gui_setup_refresh(ds);
 }
 
 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
diff --git a/vl.c b/vl.c
index 23743af..9faab75 100644
--- a/vl.c
+++ b/vl.c
@@ -1287,6 +1287,29 @@ static void gui_update(void *opaque)
     qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
 }
 
+void gui_setup_refresh(DisplayState *ds)
+{
+    DisplayChangeListener *dcl;
+    bool need_timer = false;
+
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
+        if (dcl->dpy_refresh != NULL) {
+            need_timer = true;
+            break;
+        }
+    }
+
+    if (need_timer && ds->gui_timer == NULL) {
+        ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
+        qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
+    }
+    if (!need_timer && ds->gui_timer != NULL) {
+        qemu_del_timer(ds->gui_timer);
+        qemu_free_timer(ds->gui_timer);
+        ds->gui_timer = NULL;
+    }
+}
+
 struct vm_change_state_entry {
     VMChangeStateHandler *cb;
     void *opaque;
@@ -2370,7 +2393,6 @@ int main(int argc, char **argv, char **envp)
     const char *kernel_filename, *kernel_cmdline;
     char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
     DisplayState *ds;
-    DisplayChangeListener *dcl;
     int cyls, heads, secs, translation;
     QemuOpts *hda_opts = NULL, *opts, *machine_opts;
     QemuOptsList *olist;
@@ -3725,13 +3747,6 @@ int main(int argc, char **argv, char **envp)
 
     /* display setup */
     dpy_resize(ds);
-    QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->dpy_refresh != NULL) {
-            ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
-            qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
-            break;
-        }
-    }
     text_consoles_set_display(ds);
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 3/8] console: move set_mouse + cursor_define callbacks
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 1/8] console: QLIST-ify display change listeners Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 4/8] console: s/TextConsole/QemuConsole/ Gerd Hoffmann
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

When adding DisplayChangeListeners the set_mouse and cursor_define
callbacks have been left in DisplayState for some reason.  Fix it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c          |    2 +-
 console.h          |   39 +++++++++++++++++++++++++++++++++++----
 hw/jazz_led.c      |    2 +-
 hw/qxl-render.c    |    2 +-
 hw/vga.c           |   10 +++++-----
 hw/vmware_vga.c    |   11 ++++++-----
 ui/sdl.c           |    8 ++++----
 ui/spice-display.c |    4 ++--
 ui/vnc.c           |    8 ++++----
 9 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/console.c b/console.c
index 3f3d254..260a029 100644
--- a/console.c
+++ b/console.c
@@ -1242,7 +1242,7 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
         s->text_y[1] = 0;
     }
     if (s->cursor_invalidate) {
-        dpy_cursor(s->ds, s->x, s->y);
+        dpy_text_cursor(s->ds, s->x, s->y);
         s->cursor_invalidate = 0;
     }
 }
diff --git a/console.h b/console.h
index 48fef22..bef2d2d 100644
--- a/console.h
+++ b/console.h
@@ -164,6 +164,9 @@ struct DisplayChangeListener {
                      int w, int h, uint32_t c);
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
+    void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
+    void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
+
     QLIST_ENTRY(DisplayChangeListener) next;
 };
 
@@ -181,9 +184,6 @@ struct DisplayState {
     struct DisplayAllocator* allocator;
     QLIST_HEAD(, DisplayChangeListener) listeners;
 
-    void (*mouse_set)(int x, int y, int on);
-    void (*cursor_define)(QEMUCursor *cursor);
-
     struct DisplayState *next;
 };
 
@@ -304,7 +304,7 @@ static inline void dpy_fill(struct DisplayState *s, int x, int y,
     }
 }
 
-static inline void dpy_cursor(struct DisplayState *s, int x, int y)
+static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -314,6 +314,37 @@ static inline void dpy_cursor(struct DisplayState *s, int x, int y)
     }
 }
 
+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;
+}
+
 static inline int ds_get_linesize(DisplayState *ds)
 {
     return ds->surface->linesize;
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 6486523..c4d54e2 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -210,7 +210,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
     LedState *s = opaque;
     char buf[2];
 
-    dpy_cursor(s->ds, -1, -1);
+    dpy_text_cursor(s->ds, -1, -1);
     qemu_console_resize(s->ds, 2, 1);
 
     /* TODO: draw the segments */
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index b66c168..e8cf29e 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -234,7 +234,7 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
         return 1;
     }
 
-    if (!qxl->ssd.ds->mouse_set || !qxl->ssd.ds->cursor_define) {
+    if (!dpy_cursor_define_supported(qxl->ssd.ds)) {
         return 0;
     }
 
diff --git a/hw/vga.c b/hw/vga.c
index afaef0d..ec4f0c5 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2081,11 +2081,11 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
-                dpy_cursor(s->ds,
-                           TEXTMODE_X(cursor_offset),
-                           TEXTMODE_Y(cursor_offset));
+                dpy_text_cursor(s->ds,
+                                TEXTMODE_X(cursor_offset),
+                                TEXTMODE_Y(cursor_offset));
             else
-                dpy_cursor(s->ds, -1, -1);
+                dpy_text_cursor(s->ds, -1, -1);
             s->cursor_offset = cursor_offset;
             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
@@ -2146,7 +2146,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     /* Display a message */
     s->last_width = 60;
     s->last_height = height = 3;
-    dpy_cursor(s->ds, -1, -1);
+    dpy_text_cursor(s->ds, -1, -1);
     s->ds->surface->width = s->last_width;
     s->ds->surface->height = height;
     dpy_resize(s->ds);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 6f7074e..8eded47 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -478,8 +478,7 @@ static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,
         qc = cursor_builtin_left_ptr();
     }
 
-    if (s->vga.ds->cursor_define)
-        s->vga.ds->cursor_define(qc);
+    dpy_cursor_define(s->vga.ds, qc);
     cursor_put(qc);
 }
 #endif
@@ -754,9 +753,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
         caps |= SVGA_CAP_RECT_FILL;
 #endif
 #ifdef HW_MOUSE_ACCEL
-        if (s->vga.ds->mouse_set)
+        if (dpy_cursor_define_supported(s->vga.ds)) {
             caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
                     SVGA_CAP_CURSOR_BYPASS;
+        }
 #endif
         return caps;
 
@@ -903,8 +903,9 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
         s->cursor.on |= (value == SVGA_CURSOR_ON_SHOW);
         s->cursor.on &= (value != SVGA_CURSOR_ON_HIDE);
 #ifdef HW_MOUSE_ACCEL
-        if (s->vga.ds->mouse_set && value <= SVGA_CURSOR_ON_SHOW)
-            s->vga.ds->mouse_set(s->cursor.x, s->cursor.y, s->cursor.on);
+        if (value <= SVGA_CURSOR_ON_SHOW) {
+            dpy_mouse_set(s->vga.ds, s->cursor.x, s->cursor.y, s->cursor.on);
+        }
 #endif
         break;
 
diff --git a/ui/sdl.c b/ui/sdl.c
index f6f711c..f8ead93 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -905,7 +905,7 @@ static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
     SDL_FillRect(real_screen, &dst, c);
 }
 
-static void sdl_mouse_warp(int x, int y, int on)
+static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
 {
     if (on) {
         if (!guest_cursor)
@@ -921,7 +921,7 @@ static void sdl_mouse_warp(int x, int y, int on)
     guest_x = x, guest_y = y;
 }
 
-static void sdl_mouse_define(QEMUCursor *c)
+static void sdl_mouse_define(DisplayState *ds, QEMUCursor *c)
 {
     uint8_t *image, *mask;
     int bpl;
@@ -1025,8 +1025,8 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     dcl->dpy_refresh = sdl_refresh;
     dcl->dpy_setdata = sdl_setdata;
     dcl->dpy_fill = sdl_fill;
-    ds->mouse_set = sdl_mouse_warp;
-    ds->cursor_define = sdl_mouse_define;
+    dcl->dpy_mouse_set = sdl_mouse_warp;
+    dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
 
     da = g_malloc0(sizeof(DisplayAllocator));
diff --git a/ui/spice-display.c b/ui/spice-display.c
index b61764f..5779fa8 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -404,12 +404,12 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
 void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 {
     if (ssd->cursor) {
-        ssd->ds->cursor_define(ssd->cursor);
+        dpy_cursor_define(ssd->ds, ssd->cursor);
         cursor_put(ssd->cursor);
         ssd->cursor = NULL;
     }
     if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
-        ssd->ds->mouse_set(ssd->mouse_x, ssd->mouse_y, 1);
+        dpy_mouse_set(ssd->ds, ssd->mouse_x, ssd->mouse_y, 1);
         ssd->mouse_x = -1;
         ssd->mouse_y = -1;
     }
diff --git a/ui/vnc.c b/ui/vnc.c
index 33e6386..87bd224 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -802,7 +802,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
     }
 }
 
-static void vnc_mouse_set(int x, int y, int visible)
+static void vnc_mouse_set(DisplayState *ds, int x, int y, int visible)
 {
     /* can we ask the client(s) to move the pointer ??? */
 }
@@ -829,7 +829,7 @@ static int vnc_cursor_define(VncState *vs)
     return -1;
 }
 
-static void vnc_dpy_cursor_define(QEMUCursor *c)
+static void vnc_dpy_cursor_define(DisplayState *ds, QEMUCursor *c)
 {
     VncDisplay *vd = vnc_display;
     VncState *vs;
@@ -2755,9 +2755,9 @@ void vnc_display_init(DisplayState *ds)
     dcl->dpy_update = vnc_dpy_update;
     dcl->dpy_resize = vnc_dpy_resize;
     dcl->dpy_setdata = vnc_dpy_setdata;
+    dcl->dpy_mouse_set = vnc_mouse_set;
+    dcl->dpy_cursor_define = vnc_dpy_cursor_define;
     register_displaychangelistener(ds, dcl);
-    ds->mouse_set = vnc_mouse_set;
-    ds->cursor_define = vnc_dpy_cursor_define;
 }
 
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 4/8] console: s/TextConsole/QemuConsole/
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 3/8] console: move set_mouse + cursor_define callbacks Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 5/8] console: untangle gfx & txt updates Gerd Hoffmann
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c     |   72 ++++++++++++++++++++++++++++----------------------------
 qemu-common.h |    3 +-
 2 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/console.c b/console.c
index 260a029..b53dc1b 100644
--- a/console.c
+++ b/console.c
@@ -114,20 +114,20 @@ typedef enum {
     TEXT_CONSOLE_FIXED_SIZE
 } console_type_t;
 
-/* ??? This is mis-named.
-   It is used for both text and graphical consoles.  */
-struct TextConsole {
+struct QemuConsole {
     int index;
     console_type_t console_type;
     DisplayState *ds;
+
     /* Graphic console state.  */
     vga_hw_update_ptr hw_update;
     vga_hw_invalidate_ptr hw_invalidate;
     vga_hw_screen_dump_ptr hw_screen_dump;
     vga_hw_text_update_ptr hw_text_update;
     void *hw;
-
     int g_width, g_height;
+
+    /* Text console state */
     int width;
     int height;
     int total_height;
@@ -161,8 +161,8 @@ struct TextConsole {
 };
 
 static DisplayState *display_state;
-static TextConsole *active_console;
-static TextConsole *consoles[MAX_CONSOLES];
+static QemuConsole *active_console;
+static QemuConsole *consoles[MAX_CONSOLES];
 static int nb_consoles = 0;
 
 void vga_hw_update(void)
@@ -179,7 +179,7 @@ void vga_hw_invalidate(void)
 
 void qmp_screendump(const char *filename, Error **errp)
 {
-    TextConsole *previous_active_console;
+    QemuConsole *previous_active_console;
     bool cswitch;
 
     previous_active_console = active_console;
@@ -521,7 +521,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
     }
 }
 
-static void text_console_resize(TextConsole *s)
+static void text_console_resize(QemuConsole *s)
 {
     TextCell *cells, *c, *c1;
     int w1, x, y, last_width;
@@ -553,7 +553,7 @@ static void text_console_resize(TextConsole *s)
     s->cells = cells;
 }
 
-static inline void text_update_xy(TextConsole *s, int x, int y)
+static inline void text_update_xy(QemuConsole *s, int x, int y)
 {
     s->text_x[0] = MIN(s->text_x[0], x);
     s->text_x[1] = MAX(s->text_x[1], x);
@@ -561,7 +561,7 @@ static inline void text_update_xy(TextConsole *s, int x, int y)
     s->text_y[1] = MAX(s->text_y[1], y);
 }
 
-static void invalidate_xy(TextConsole *s, int x, int y)
+static void invalidate_xy(QemuConsole *s, int x, int y)
 {
     if (s->update_x0 > x * FONT_WIDTH)
         s->update_x0 = x * FONT_WIDTH;
@@ -573,7 +573,7 @@ static void invalidate_xy(TextConsole *s, int x, int y)
         s->update_y1 = (y + 1) * FONT_HEIGHT;
 }
 
-static void update_xy(TextConsole *s, int x, int y)
+static void update_xy(QemuConsole *s, int x, int y)
 {
     TextCell *c;
     int y1, y2;
@@ -597,7 +597,7 @@ static void update_xy(TextConsole *s, int x, int y)
     }
 }
 
-static void console_show_cursor(TextConsole *s, int show)
+static void console_show_cursor(QemuConsole *s, int show)
 {
     TextCell *c;
     int y, y1;
@@ -631,7 +631,7 @@ static void console_show_cursor(TextConsole *s, int show)
     }
 }
 
-static void console_refresh(TextConsole *s)
+static void console_refresh(QemuConsole *s)
 {
     TextCell *c;
     int x, y, y1;
@@ -666,7 +666,7 @@ static void console_refresh(TextConsole *s)
 
 static void console_scroll(int ydelta)
 {
-    TextConsole *s;
+    QemuConsole *s;
     int i, y1;
 
     s = active_console;
@@ -698,7 +698,7 @@ static void console_scroll(int ydelta)
     console_refresh(s);
 }
 
-static void console_put_lf(TextConsole *s)
+static void console_put_lf(QemuConsole *s)
 {
     TextCell *c;
     int x, y1;
@@ -749,7 +749,7 @@ static void console_put_lf(TextConsole *s)
  * NOTE: I know this code is not very efficient (checking every color for it
  * self) but it is more readable and better maintainable.
  */
-static void console_handle_escape(TextConsole *s)
+static void console_handle_escape(QemuConsole *s)
 {
     int i;
 
@@ -842,7 +842,7 @@ static void console_handle_escape(TextConsole *s)
     }
 }
 
-static void console_clear_xy(TextConsole *s, int x, int y)
+static void console_clear_xy(QemuConsole *s, int x, int y)
 {
     int y1 = (s->y_base + y) % s->total_height;
     TextCell *c = &s->cells[y1 * s->width + x];
@@ -852,7 +852,7 @@ static void console_clear_xy(TextConsole *s, int x, int y)
 }
 
 /* set cursor, checking bounds */
-static void set_cursor(TextConsole *s, int x, int y)
+static void set_cursor(QemuConsole *s, int x, int y)
 {
     if (x < 0) {
         x = 0;
@@ -871,7 +871,7 @@ static void set_cursor(TextConsole *s, int x, int y)
     s->y = y;
 }
 
-static void console_putchar(TextConsole *s, int ch)
+static void console_putchar(QemuConsole *s, int ch)
 {
     TextCell *c;
     int y1, i;
@@ -1078,7 +1078,7 @@ static void console_putchar(TextConsole *s, int ch)
 
 void console_select(unsigned int index)
 {
-    TextConsole *s;
+    QemuConsole *s;
 
     if (index >= MAX_CONSOLES)
         return;
@@ -1111,7 +1111,7 @@ void console_select(unsigned int index)
 
 static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
 {
-    TextConsole *s = chr->opaque;
+    QemuConsole *s = chr->opaque;
     int i;
 
     s->update_x0 = s->width * FONT_WIDTH;
@@ -1133,7 +1133,7 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
 
 static void kbd_send_chars(void *opaque)
 {
-    TextConsole *s = opaque;
+    QemuConsole *s = opaque;
     int len;
     uint8_t buf[16];
 
@@ -1156,7 +1156,7 @@ static void kbd_send_chars(void *opaque)
 /* called when an ascii key is pressed */
 void kbd_put_keysym(int keysym)
 {
-    TextConsole *s;
+    QemuConsole *s;
     uint8_t buf[16], *q;
     int c;
 
@@ -1211,7 +1211,7 @@ void kbd_put_keysym(int keysym)
 
 static void text_console_invalidate(void *opaque)
 {
-    TextConsole *s = (TextConsole *) opaque;
+    QemuConsole *s = (QemuConsole *) opaque;
     if (!ds_get_bits_per_pixel(s->ds) && s->console_type == TEXT_CONSOLE) {
         s->g_width = ds_get_width(s->ds);
         s->g_height = ds_get_height(s->ds);
@@ -1222,7 +1222,7 @@ static void text_console_invalidate(void *opaque)
 
 static void text_console_update(void *opaque, console_ch_t *chardata)
 {
-    TextConsole *s = (TextConsole *) opaque;
+    QemuConsole *s = (QemuConsole *) opaque;
     int i, j, src;
 
     if (s->text_x[0] <= s->text_x[1]) {
@@ -1247,10 +1247,10 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
     }
 }
 
-static TextConsole *get_graphic_console(DisplayState *ds)
+static QemuConsole *get_graphic_console(DisplayState *ds)
 {
     int i;
-    TextConsole *s;
+    QemuConsole *s;
     for (i = 0; i < nb_consoles; i++) {
         s = consoles[i];
         if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds)
@@ -1259,14 +1259,14 @@ static TextConsole *get_graphic_console(DisplayState *ds)
     return NULL;
 }
 
-static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
+static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
 {
-    TextConsole *s;
+    QemuConsole *s;
     int i;
 
     if (nb_consoles >= MAX_CONSOLES)
         return NULL;
-    s = g_malloc0(sizeof(TextConsole));
+    s = g_malloc0(sizeof(QemuConsole));
     if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
         (console_type == GRAPHIC_CONSOLE))) {
         active_console = s;
@@ -1417,7 +1417,7 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
                                    vga_hw_text_update_ptr text_update,
                                    void *opaque)
 {
-    TextConsole *s;
+    QemuConsole *s;
     DisplayState *ds;
 
     ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
@@ -1463,14 +1463,14 @@ void console_color_init(DisplayState *ds)
 
 static void text_console_set_echo(CharDriverState *chr, bool echo)
 {
-    TextConsole *s = chr->opaque;
+    QemuConsole *s = chr->opaque;
 
     s->echo = echo;
 }
 
 static void text_console_update_cursor(void *opaque)
 {
-    TextConsole *s = opaque;
+    QemuConsole *s = opaque;
 
     s->cursor_visible_phase = !s->cursor_visible_phase;
     vga_hw_invalidate();
@@ -1480,7 +1480,7 @@ static void text_console_update_cursor(void *opaque)
 
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 {
-    TextConsole *s;
+    QemuConsole *s;
     static int color_inited;
 
     s = chr->opaque;
@@ -1543,7 +1543,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 CharDriverState *text_console_init(QemuOpts *opts)
 {
     CharDriverState *chr;
-    TextConsole *s;
+    QemuConsole *s;
     unsigned width;
     unsigned height;
 
@@ -1589,7 +1589,7 @@ void text_consoles_set_display(DisplayState *ds)
 
 void qemu_console_resize(DisplayState *ds, int width, int height)
 {
-    TextConsole *s = get_graphic_console(ds);
+    QemuConsole *s = get_graphic_console(ds);
     if (!s) return;
 
     s->g_width = width;
diff --git a/qemu-common.h b/qemu-common.h
index b54612b..fdd0dbc 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -264,8 +264,7 @@ typedef struct DisplayChangeListener DisplayChangeListener;
 typedef struct DisplaySurface DisplaySurface;
 typedef struct DisplayAllocator DisplayAllocator;
 typedef struct PixelFormat PixelFormat;
-typedef struct TextConsole TextConsole;
-typedef TextConsole QEMUConsole;
+typedef struct QemuConsole QemuConsole;
 typedef struct CharDriverState CharDriverState;
 typedef struct MACAddr MACAddr;
 typedef struct NetClientState NetClientState;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 5/8] console: untangle gfx & txt updates
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 4/8] console: s/TextConsole/QemuConsole/ Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 6/8] console: init displaychangelisteners on register Gerd Hoffmann
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Stop abusing displaysurface fields for text mode displays.
(bpp = 0, width = cols, height = lines).

Add flags to displaystate indicating whenever text mode display
(curses) or gfx mode displays (sdl, vnc, ...) are present.

Add separate displaychangelistener callbacks for text / gfx mode
resize & updates.

This allows to enable gfx and txt diplays at the same time and also
paves the way for more cleanups in the future.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c            |   59 +++++++++++++++++++++-------------------
 console.h            |   74 +++++++++++++++++++++++++++++++++++---------------
 hw/blizzard.c        |    4 +-
 hw/exynos4210_fimd.c |    2 +-
 hw/g364fb.c          |    7 +++--
 hw/jazz_led.c        |    4 +-
 hw/milkymist-vgafb.c |    2 +-
 hw/musicpal.c        |    2 +-
 hw/nseries.c         |    2 +-
 hw/omap_lcdc.c       |    2 +-
 hw/palm.c            |    2 +-
 hw/pl110.c           |    2 +-
 hw/pxa2xx_lcd.c      |    8 +++---
 hw/qxl-render.c      |   10 +++---
 hw/qxl.c             |    4 +-
 hw/sm501.c           |    4 +-
 hw/ssd0303.c         |    2 +-
 hw/ssd0323.c         |    2 +-
 hw/tc6393xb.c        |    4 +-
 hw/tcx.c             |   16 +++++-----
 hw/vga.c             |   34 ++++++++++-------------
 hw/vmware_vga.c      |    4 +-
 ui/curses.c          |   21 +++++---------
 ui/sdl.c             |   12 ++++----
 ui/spice-display.c   |    4 +-
 ui/vnc.c             |    8 +++---
 vl.c                 |   14 ++++++++-
 27 files changed, 171 insertions(+), 138 deletions(-)

diff --git a/console.c b/console.c
index b53dc1b..61812c7 100644
--- a/console.c
+++ b/console.c
@@ -638,30 +638,33 @@ static void console_refresh(QemuConsole *s)
 
     if (s != active_console)
         return;
-    if (!ds_get_bits_per_pixel(s->ds)) {
+
+    if (s->ds->have_text) {
         s->text_x[0] = 0;
         s->text_y[0] = 0;
         s->text_x[1] = s->width - 1;
         s->text_y[1] = s->height - 1;
         s->cursor_invalidate = 1;
-        return;
     }
 
-    vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
-                  color_table[0][COLOR_BLACK]);
-    y1 = s->y_displayed;
-    for(y = 0; y < s->height; y++) {
-        c = s->cells + y1 * s->width;
-        for(x = 0; x < s->width; x++) {
-            vga_putcharxy(s->ds, x, y, c->ch,
-                          &(c->t_attrib));
-            c++;
+    if (s->ds->have_gfx) {
+        vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
+                      color_table[0][COLOR_BLACK]);
+        y1 = s->y_displayed;
+        for (y = 0; y < s->height; y++) {
+            c = s->cells + y1 * s->width;
+            for (x = 0; x < s->width; x++) {
+                vga_putcharxy(s->ds, x, y, c->ch,
+                              &(c->t_attrib));
+                c++;
+            }
+            if (++y1 == s->total_height) {
+                y1 = 0;
+            }
         }
-        if (++y1 == s->total_height)
-            y1 = 0;
+        console_show_cursor(s, 1);
+        dpy_gfx_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
     }
-    console_show_cursor(s, 1);
-    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
 }
 
 static void console_scroll(int ydelta)
@@ -1094,17 +1097,17 @@ void console_select(unsigned int index)
             qemu_del_timer(active_console->cursor_timer);
         }
         active_console = s;
-        if (ds_get_bits_per_pixel(s->ds)) {
+        if (ds->have_gfx) {
             ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
-        } else {
-            s->ds->surface->width = s->width;
-            s->ds->surface->height = s->height;
+            dpy_gfx_resize(ds);
+        }
+        if (ds->have_text) {
+            dpy_text_resize(ds, s->width, s->height);
         }
         if (s->cursor_timer) {
             qemu_mod_timer(s->cursor_timer,
                    qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
         }
-        dpy_resize(s->ds);
         vga_hw_invalidate();
     }
 }
@@ -1123,10 +1126,10 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
         console_putchar(s, buf[i]);
     }
     console_show_cursor(s, 1);
-    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
-        dpy_update(s->ds, s->update_x0, s->update_y0,
-                   s->update_x1 - s->update_x0,
-                   s->update_y1 - s->update_y0);
+    if (s->ds->have_gfx && s->update_x0 < s->update_x1) {
+        dpy_gfx_update(s->ds, s->update_x0, s->update_y0,
+                       s->update_x1 - s->update_x0,
+                       s->update_y1 - s->update_y0);
     }
     return len;
 }
@@ -1234,8 +1237,8 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
                                 (s->cells[src].t_attrib.fgcol << 12) |
                                 (s->cells[src].t_attrib.bgcol << 8) |
                                 (s->cells[src].t_attrib.bold << 21));
-        dpy_update(s->ds, s->text_x[0], s->text_y[0],
-                   s->text_x[1] - s->text_x[0], i - s->text_y[0]);
+        dpy_text_update(s->ds, s->text_x[0], s->text_y[0],
+                        s->text_x[1] - s->text_x[0], i - s->text_y[0]);
         s->text_x[0] = s->width;
         s->text_y[0] = s->height;
         s->text_x[1] = 0;
@@ -1596,7 +1599,7 @@ void qemu_console_resize(DisplayState *ds, int width, int height)
     s->g_height = height;
     if (is_graphic_console()) {
         ds->surface = qemu_resize_displaysurface(ds, width, height);
-        dpy_resize(ds);
+        dpy_gfx_resize(ds);
     }
 }
 
@@ -1604,7 +1607,7 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
                        int dst_x, int dst_y, int w, int h)
 {
     if (is_graphic_console()) {
-        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
+        dpy_gfx_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
     }
 }
 
diff --git a/console.h b/console.h
index bef2d2d..9d008b2 100644
--- a/console.h
+++ b/console.h
@@ -154,15 +154,19 @@ struct DisplayChangeListener {
     int idle;
     uint64_t gui_timer_interval;
 
-    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
-    void (*dpy_resize)(struct DisplayState *s);
-    void (*dpy_setdata)(struct DisplayState *s);
     void (*dpy_refresh)(struct DisplayState *s);
-    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
-                     int dst_x, int dst_y, int w, int h);
-    void (*dpy_fill)(struct DisplayState *s, int x, int y,
-                     int w, int h, uint32_t c);
+
+    void (*dpy_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,
+                         int dst_x, int dst_y, int w, int h);
+    void (*dpy_gfx_fill)(struct DisplayState *s, int x, int y,
+                         int w, int h, uint32_t c);
+
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
+    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_mouse_set)(struct DisplayState *s, int x, int y, int on);
     void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
@@ -180,6 +184,8 @@ struct DisplayState {
     struct DisplaySurface *surface;
     void *opaque;
     struct QEMUTimer *gui_timer;
+    bool have_gfx;
+    bool have_text;
 
     struct DisplayAllocator* allocator;
     QLIST_HEAD(, DisplayChangeListener) listeners;
@@ -244,28 +250,32 @@ static inline void unregister_displaychangelistener(DisplayState *ds,
     gui_setup_refresh(ds);
 }
 
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
+static inline void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        dcl->dpy_update(s, x, y, w, h);
+        if (dcl->dpy_gfx_update) {
+            dcl->dpy_gfx_update(s, x, y, w, h);
+        }
     }
 }
 
-static inline void dpy_resize(DisplayState *s)
+static inline void dpy_gfx_resize(DisplayState *s)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        dcl->dpy_resize(s);
+        if (dcl->dpy_gfx_resize) {
+            dcl->dpy_gfx_resize(s);
+        }
     }
 }
 
-static inline void dpy_setdata(DisplayState *s)
+static inline void dpy_gfx_setdata(DisplayState *s)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_setdata) {
-            dcl->dpy_setdata(s);
+        if (dcl->dpy_gfx_setdata) {
+            dcl->dpy_gfx_setdata(s);
         }
     }
 }
@@ -280,26 +290,26 @@ static inline void dpy_refresh(DisplayState *s)
     }
 }
 
-static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
+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_copy) {
-            dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
+        if (dcl->dpy_gfx_copy) {
+            dcl->dpy_gfx_copy(s, src_x, src_y, dst_x, dst_y, w, h);
         } else { /* TODO */
-            dcl->dpy_update(s, dst_x, dst_y, w, h);
+            dcl->dpy_gfx_update(s, dst_x, dst_y, w, h);
         }
     }
 }
 
-static inline void dpy_fill(struct DisplayState *s, int x, int y,
-                             int w, int h, uint32_t c)
+static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
+                                int w, int h, uint32_t c)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_fill) {
-            dcl->dpy_fill(s, x, y, w, h, c);
+        if (dcl->dpy_gfx_fill) {
+            dcl->dpy_gfx_fill(s, x, y, w, h, c);
         }
     }
 }
@@ -314,6 +324,26 @@ static inline void dpy_text_cursor(struct DisplayState *s, int x, int 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;
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 06e19b3..1b57eb5 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -921,8 +921,8 @@ static void blizzard_update_display(void *opaque)
     for (; y < s->my[1]; y ++, src += bypl, dst += bypl)
         memcpy(dst, src, bwidth);
 
-    dpy_update(s->state, s->mx[0], s->my[0],
-                    s->mx[1] - s->mx[0], y - s->my[0]);
+    dpy_gfx_update(s->state, s->mx[0], s->my[0],
+                   s->mx[1] - s->mx[0], y - s->my[0]);
 
     s->mx[0] = s->x;
     s->mx[1] = 0;
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 3313f00..8cc410f 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1307,7 +1307,7 @@ static void exynos4210_fimd_update(void *opaque)
             fimd_copy_line_toqemu(global_width, s->ifb + global_width * line *
                     RGBA_SIZE, d + global_width * line * bpp);
         }
-        dpy_update(s->console, 0, 0, global_width, global_height);
+        dpy_gfx_update(s->console, 0, 0, global_width, global_height);
     }
     s->invalidate = false;
     s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND;
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 059e622..4f3b1db 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -197,7 +197,8 @@ static void g364fb_draw_graphic8(G364State *s)
                 reset_dirty(s, page_min, page_max);
                 page_min = (ram_addr_t)-1;
                 page_max = 0;
-                dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
+                dpy_gfx_update(s->ds, xmin, ymin,
+                               xmax - xmin + 1, ymax - ymin + 1);
                 xmin = s->width;
                 xmax = 0;
                 ymin = s->height;
@@ -216,7 +217,7 @@ static void g364fb_draw_graphic8(G364State *s)
 
 done:
     if (page_min != (ram_addr_t)-1) {
-        dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
+        dpy_gfx_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
         reset_dirty(s, page_min, page_max);
     }
 }
@@ -238,7 +239,7 @@ static void g364fb_draw_blank(G364State *s)
         d += ds_get_linesize(s->ds);
     }
 
-    dpy_update(s->ds, 0, 0, s->width, s->height);
+    dpy_gfx_update(s->ds, 0, 0, s->width, s->height);
     s->blanked = 1;
 }
 
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index c4d54e2..d3767ed 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -196,7 +196,7 @@ static void jazz_led_update_display(void *opaque)
     }
 
     s->state = REDRAW_NONE;
-    dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
+    dpy_gfx_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
 }
 
 static void jazz_led_invalidate_display(void *opaque)
@@ -218,7 +218,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
     console_write_ch(chardata++, 0x00200100 | buf[0]);
     console_write_ch(chardata++, 0x00200100 | buf[1]);
 
-    dpy_update(s->ds, 0, 0, 2, 1);
+    dpy_text_update(s->ds, 0, 0, 2, 1);
 }
 
 static int jazz_led_post_load(void *opaque, int version_id)
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index cd4365d..dc40a43 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -134,7 +134,7 @@ static void vgafb_update_display(void *opaque)
                                &first, &last);
 
     if (first >= 0) {
-        dpy_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
+        dpy_gfx_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
     }
     s->invalidate = 0;
 }
diff --git a/hw/musicpal.c b/hw/musicpal.c
index f305e21..0300495 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -526,7 +526,7 @@ static void lcd_refresh(void *opaque)
                   ds_get_bits_per_pixel(s->ds));
     }
 
-    dpy_update(s->ds, 0, 0, 128*3, 64*3);
+    dpy_gfx_update(s->ds, 0, 0, 128*3, 64*3);
 }
 
 static void lcd_invalidate(void *opaque)
diff --git a/hw/nseries.c b/hw/nseries.c
index 6df71eb..114c739 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1375,7 +1375,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
        size until the guest activates the display.  */
     ds = get_displaystate();
     ds->surface = qemu_resize_displaysurface(ds, 800, 480);
-    dpy_resize(ds);
+    dpy_gfx_resize(ds);
 }
 
 static struct arm_boot_info n800_binfo = {
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index e2ba108..839d9cc 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -219,7 +219,7 @@ static void omap_update_display(void *opaque)
                                draw_line, omap_lcd->palette,
                                &first, &last);
     if (first >= 0) {
-        dpy_update(omap_lcd->state, 0, first, width, last - first + 1);
+        dpy_gfx_update(omap_lcd->state, 0, first, width, last - first + 1);
     }
     omap_lcd->invalidate = 0;
 }
diff --git a/hw/palm.c b/hw/palm.c
index bacdc90..fe12b3c 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -272,7 +272,7 @@ static void palmte_init(ram_addr_t ram_size,
        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_resize(ds);
+    dpy_gfx_resize(ds);
 }
 
 static QEMUMachine palmte_machine = {
diff --git a/hw/pl110.c b/hw/pl110.c
index a582640..0f4df49 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -239,7 +239,7 @@ static void pl110_update_display(void *opaque)
                                fn, s->palette,
                                &first, &last);
     if (first >= 0) {
-        dpy_update(s->ds, 0, first, s->cols, last - first + 1);
+        dpy_gfx_update(s->ds, 0, first, s->cols, last - first + 1);
     }
     s->invalidate = 0;
 }
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index ee8bf57..193d5d2 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -871,20 +871,20 @@ static void pxa2xx_update_display(void *opaque)
     if (miny >= 0) {
         switch (s->orientation) {
         case 0:
-            dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
+            dpy_gfx_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
             break;
         case 90:
-            dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
+            dpy_gfx_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
             break;
         case 180:
             maxy = s->yres - maxy - 1;
             miny = s->yres - miny - 1;
-            dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
+            dpy_gfx_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
             break;
         case 270:
             maxy = s->yres - maxy - 1;
             miny = s->yres - miny - 1;
-            dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
+            dpy_gfx_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
             break;
         }
     }
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index e8cf29e..47eb8b4 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -123,17 +123,17 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
                     qxl->guest_primary.surface.width,
                     qxl->guest_primary.surface.height);
         }
-        dpy_resize(vga->ds);
+        dpy_gfx_resize(vga->ds);
     }
     for (i = 0; i < qxl->num_dirty_rects; i++) {
         if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
             break;
         }
         qxl_blit(qxl, qxl->dirty+i);
-        dpy_update(vga->ds,
-                   qxl->dirty[i].left, qxl->dirty[i].top,
-                   qxl->dirty[i].right - qxl->dirty[i].left,
-                   qxl->dirty[i].bottom - qxl->dirty[i].top);
+        dpy_gfx_update(vga->ds,
+                       qxl->dirty[i].left, qxl->dirty[i].top,
+                       qxl->dirty[i].right - qxl->dirty[i].left,
+                       qxl->dirty[i].bottom - qxl->dirty[i].top);
     }
     qxl->num_dirty_rects = 0;
 }
diff --git a/hw/qxl.c b/hw/qxl.c
index 1d16863..3b18711 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1864,8 +1864,8 @@ static void display_refresh(struct DisplayState *ds)
 }
 
 static DisplayChangeListener display_listener = {
-    .dpy_update  = display_update,
-    .dpy_resize  = display_resize,
+    .dpy_gfx_update  = display_update,
+    .dpy_gfx_resize  = display_resize,
     .dpy_refresh = display_refresh,
 };
 
diff --git a/hw/sm501.c b/hw/sm501.c
index 786e076..1cdf5b3 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1351,7 +1351,7 @@ static void sm501_draw_crt(SM501State * s)
 	} else {
 	    if (y_start >= 0) {
 		/* flush to display */
-		dpy_update(s->ds, 0, y_start, width, y - y_start);
+                dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
 		y_start = -1;
 	    }
 	}
@@ -1362,7 +1362,7 @@ static void sm501_draw_crt(SM501State * s)
 
     /* complete flush to display */
     if (y_start >= 0)
-	dpy_update(s->ds, 0, y_start, width, y - y_start);
+        dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
 
     /* clear dirty flags */
     if (page_min != ~0l) {
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 4e1ee6e..d7fd828 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -252,7 +252,7 @@ static void ssd0303_update_display(void *opaque)
         }
     }
     s->redraw = 0;
-    dpy_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
+    dpy_gfx_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
 }
 
 static void ssd0303_invalidate_display(void * opaque)
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 9c42d64..4098830 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -260,7 +260,7 @@ static void ssd0323_update_display(void *opaque)
         }
     }
     s->redraw = 0;
-    dpy_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
+    dpy_gfx_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
 }
 
 static void ssd0323_invalidate_display(void * opaque)
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 420925c..1f1a616 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -454,7 +454,7 @@ static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
             return;
     }
 
-    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
+    dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
 }
 
 static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
@@ -472,7 +472,7 @@ static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
         d += ds_get_linesize(s->ds);
     }
 
-    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
+    dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
 }
 
 static void tc6393xb_update_display(void *opaque)
diff --git a/hw/tcx.c b/hw/tcx.c
index 2db2db1..c661427 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -268,8 +268,8 @@ static void tcx_update_display(void *opaque)
         } else {
             if (y_start >= 0) {
                 /* flush to display */
-                dpy_update(ts->ds, 0, y_start,
-                           ts->width, y - y_start);
+                dpy_gfx_update(ts->ds, 0, y_start,
+                               ts->width, y - y_start);
                 y_start = -1;
             }
             d += dd * 4;
@@ -278,8 +278,8 @@ static void tcx_update_display(void *opaque)
     }
     if (y_start >= 0) {
         /* flush to display */
-        dpy_update(ts->ds, 0, y_start,
-                   ts->width, y - y_start);
+        dpy_gfx_update(ts->ds, 0, y_start,
+                       ts->width, y - y_start);
     }
     /* reset modified pages */
     if (page_max >= page_min) {
@@ -344,8 +344,8 @@ static void tcx24_update_display(void *opaque)
         } else {
             if (y_start >= 0) {
                 /* flush to display */
-                dpy_update(ts->ds, 0, y_start,
-                           ts->width, y - y_start);
+                dpy_gfx_update(ts->ds, 0, y_start,
+                               ts->width, y - y_start);
                 y_start = -1;
             }
             d += dd * 4;
@@ -356,8 +356,8 @@ static void tcx24_update_display(void *opaque)
     }
     if (y_start >= 0) {
         /* flush to display */
-        dpy_update(ts->ds, 0, y_start,
-                   ts->width, y - y_start);
+        dpy_gfx_update(ts->ds, 0, y_start,
+                       ts->width, y - y_start);
     }
     /* reset modified pages */
     if (page_max >= page_min) {
diff --git a/hw/vga.c b/hw/vga.c
index ec4f0c5..19a68ff 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1460,8 +1460,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
             ch_attr_ptr++;
         }
         if (cx_max != -1) {
-            dpy_update(s->ds, cx_min * cw, cy * cheight,
-                       (cx_max - cx_min + 1) * cw, cheight);
+            dpy_gfx_update(s->ds, cx_min * cw, cy * cheight,
+                           (cx_max - cx_min + 1) * cw, cheight);
         }
         dest += linesize * cheight;
         line1 = line + cheight;
@@ -1697,7 +1697,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
             s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
 #endif
-            dpy_resize(s->ds);
+            dpy_gfx_resize(s->ds);
         } else {
             qemu_console_resize(s->ds, disp_width, height);
         }
@@ -1711,7 +1711,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     } else if (is_buffer_shared(s->ds->surface) &&
                (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
         s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
-        dpy_setdata(s->ds);
+        dpy_gfx_setdata(s->ds);
     }
 
     s->rgb_to_pixel =
@@ -1816,8 +1816,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         } else {
             if (y_start >= 0) {
                 /* flush to display */
-                dpy_update(s->ds, 0, y_start,
-                           disp_width, y - y_start);
+                dpy_gfx_update(s->ds, 0, y_start,
+                               disp_width, y - y_start);
                 y_start = -1;
             }
         }
@@ -1837,8 +1837,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     if (y_start >= 0) {
         /* flush to display */
-        dpy_update(s->ds, 0, y_start,
-                   disp_width, y - y_start);
+        dpy_gfx_update(s->ds, 0, y_start,
+                       disp_width, y - y_start);
     }
     /* reset modified pages */
     if (page_max >= page_min) {
@@ -1872,8 +1872,8 @@ static void vga_draw_blank(VGACommonState *s, int full_update)
         memset(d, val, w);
         d += ds_get_linesize(s->ds);
     }
-    dpy_update(s->ds, 0, 0,
-               s->last_scr_width, s->last_scr_height);
+    dpy_gfx_update(s->ds, 0, 0,
+                   s->last_scr_width, s->last_scr_height);
 }
 
 #define GMODE_TEXT     0
@@ -2063,9 +2063,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             cw != s->last_cw || cheight != s->last_ch) {
             s->last_scr_width = width * cw;
             s->last_scr_height = height * cheight;
-            s->ds->surface->width = width;
-            s->ds->surface->height = height;
-            dpy_resize(s->ds);
+            dpy_text_resize(s->ds, width, height);
             s->last_width = width;
             s->last_height = height;
             s->last_ch = cheight;
@@ -2098,7 +2096,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             for (i = 0; i < size; src ++, dst ++, i ++)
                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
 
-            dpy_update(s->ds, 0, 0, width, height);
+            dpy_text_update(s->ds, 0, 0, width, height);
         } else {
             c_max = 0;
 
@@ -2121,7 +2119,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
 
             if (c_min <= c_max) {
                 i = TEXTMODE_Y(c_min);
-                dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
+                dpy_text_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
             }
         }
 
@@ -2147,9 +2145,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     s->last_width = 60;
     s->last_height = height = 3;
     dpy_text_cursor(s->ds, -1, -1);
-    s->ds->surface->width = s->last_width;
-    s->ds->surface->height = height;
-    dpy_resize(s->ds);
+    dpy_text_resize(s->ds, s->last_width, height);
 
     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
         console_write_ch(dst ++, ' ');
@@ -2160,7 +2156,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     for (i = 0; i < size; i ++)
         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
 
-    dpy_update(s->ds, 0, 0, s->last_width, height);
+    dpy_text_update(s->ds, 0, 0, s->last_width, height);
 }
 
 static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 8eded47..62aecac 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -321,14 +321,14 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
     for (; line > 0; line --, src += bypl, dst += bypl)
         memcpy(dst, src, width);
 
-    dpy_update(s->vga.ds, x, y, w, h);
+    dpy_gfx_update(s->vga.ds, x, y, w, h);
 }
 
 static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
 {
     memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr,
            s->bypp * s->width * s->height);
-    dpy_update(s->vga.ds, 0, 0, s->width, s->height);
+    dpy_gfx_update(s->vga.ds, 0, 0, s->width, s->height);
 }
 
 static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
diff --git a/ui/curses.c b/ui/curses.c
index c2be2c6..b40b223 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -95,17 +95,16 @@ static void curses_calc_pad(void)
     }
 }
 
-static void curses_resize(DisplayState *ds)
+static void curses_resize(DisplayState *ds, int width, int height)
 {
-    if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight)
+    if (width == gwidth && height == gheight) {
         return;
+    }
 
-    gwidth = ds_get_width(ds);
-    gheight = ds_get_height(ds);
+    gwidth = width;
+    gheight = height;
 
     curses_calc_pad();
-    ds->surface->width = width * FONT_WIDTH;
-    ds->surface->height = height * FONT_HEIGHT;
 }
 
 #ifndef _WIN32
@@ -167,8 +166,6 @@ static void curses_refresh(DisplayState *ds)
         clear();
         refresh();
         curses_calc_pad();
-        ds->surface->width = FONT_WIDTH * width;
-        ds->surface->height = FONT_HEIGHT * height;
         vga_hw_invalidate();
         invalidate = 0;
     }
@@ -195,8 +192,6 @@ static void curses_refresh(DisplayState *ds)
             refresh();
             curses_calc_pad();
             curses_update(ds, 0, 0, width, height);
-            ds->surface->width = FONT_WIDTH * width;
-            ds->surface->height = FONT_HEIGHT * height;
             continue;
         }
 #endif
@@ -355,13 +350,11 @@ void curses_display_init(DisplayState *ds, int full_screen)
 #endif
 
     dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
-    dcl->dpy_update = curses_update;
-    dcl->dpy_resize = curses_resize;
+    dcl->dpy_text_update = curses_update;
+    dcl->dpy_text_resize = curses_resize;
     dcl->dpy_refresh = curses_refresh;
     dcl->dpy_text_cursor = curses_cursor_position;
     register_displaychangelistener(ds, dcl);
-    qemu_free_displaysurface(ds);
-    ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);
 
     invalidate = 1;
 }
diff --git a/ui/sdl.c b/ui/sdl.c
index f8ead93..fac1a47 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -553,7 +553,7 @@ static void sdl_scale(DisplayState *ds, int width, int height)
     if (!is_buffer_shared(ds->surface)) {
         ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds),
                                                  ds_get_height(ds));
-        dpy_resize(ds);
+        dpy_gfx_resize(ds);
     }
 }
 
@@ -1020,11 +1020,11 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     }
 
     dcl = g_malloc0(sizeof(DisplayChangeListener));
-    dcl->dpy_update = sdl_update;
-    dcl->dpy_resize = sdl_resize;
+    dcl->dpy_gfx_update = sdl_update;
+    dcl->dpy_gfx_resize = sdl_resize;
     dcl->dpy_refresh = sdl_refresh;
-    dcl->dpy_setdata = sdl_setdata;
-    dcl->dpy_fill = sdl_fill;
+    dcl->dpy_gfx_setdata = sdl_setdata;
+    dcl->dpy_gfx_fill = sdl_fill;
     dcl->dpy_mouse_set = sdl_mouse_warp;
     dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
@@ -1034,7 +1034,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     da->resize_displaysurface = sdl_resize_displaysurface;
     da->free_displaysurface = sdl_free_displaysurface;
     if (register_displayallocator(ds, da) == da) {
-        dpy_resize(ds);
+        dpy_gfx_resize(ds);
     }
 
     mouse_mode_notifier.notify = sdl_mouse_mode_change;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 5779fa8..fb99148 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -571,8 +571,8 @@ static void display_refresh(struct DisplayState *ds)
 }
 
 static DisplayChangeListener display_listener = {
-    .dpy_update  = display_update,
-    .dpy_resize  = display_resize,
+    .dpy_gfx_update  = display_update,
+    .dpy_gfx_resize  = display_resize,
     .dpy_refresh = display_refresh,
 };
 
diff --git a/ui/vnc.c b/ui/vnc.c
index 87bd224..a192e61 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2751,10 +2751,10 @@ void vnc_display_init(DisplayState *ds)
     qemu_mutex_init(&vs->mutex);
     vnc_start_worker_thread();
 
-    dcl->dpy_copy = vnc_dpy_copy;
-    dcl->dpy_update = vnc_dpy_update;
-    dcl->dpy_resize = vnc_dpy_resize;
-    dcl->dpy_setdata = vnc_dpy_setdata;
+    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;
     register_displaychangelistener(ds, dcl);
diff --git a/vl.c b/vl.c
index 9faab75..ec94626 100644
--- a/vl.c
+++ b/vl.c
@@ -1291,11 +1291,18 @@ void gui_setup_refresh(DisplayState *ds)
 {
     DisplayChangeListener *dcl;
     bool need_timer = false;
+    bool have_gfx = false;
+    bool have_text = false;
 
     QLIST_FOREACH(dcl, &ds->listeners, next) {
         if (dcl->dpy_refresh != NULL) {
             need_timer = true;
-            break;
+        }
+        if (dcl->dpy_gfx_update != NULL) {
+            have_gfx = true;
+        }
+        if (dcl->dpy_text_update != NULL) {
+            have_text = true;
         }
     }
 
@@ -1308,6 +1315,9 @@ void gui_setup_refresh(DisplayState *ds)
         qemu_free_timer(ds->gui_timer);
         ds->gui_timer = NULL;
     }
+
+    ds->have_gfx = have_gfx;
+    ds->have_text = have_text;
 }
 
 struct vm_change_state_entry {
@@ -3746,7 +3756,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 
     /* display setup */
-    dpy_resize(ds);
+    dpy_gfx_resize(ds);
     text_consoles_set_display(ds);
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 6/8] console: init displaychangelisteners on register
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 5/8] console: untangle gfx & txt updates Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 7/8] vga: fix text mode updating Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 8/8] console: remove dpy_gfx_fill Gerd Hoffmann
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h |    3 +++
 vl.c      |    1 -
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/console.h b/console.h
index 9d008b2..bd56f3c 100644
--- a/console.h
+++ b/console.h
@@ -241,6 +241,9 @@ static inline void register_displaychangelistener(DisplayState *ds, DisplayChang
 {
     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,
diff --git a/vl.c b/vl.c
index ec94626..91514c8 100644
--- a/vl.c
+++ b/vl.c
@@ -3756,7 +3756,6 @@ int main(int argc, char **argv, char **envp)
 #endif
 
     /* display setup */
-    dpy_gfx_resize(ds);
     text_consoles_set_display(ds);
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 7/8] vga: fix text mode updating
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 6/8] console: init displaychangelisteners on register Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 8/8] console: remove dpy_gfx_fill Gerd Hoffmann
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

With both text (curses) and graphics (vnc/sdl/spice/...) display active
vga text mode emulation fails to update both correctly.  Depending on
whenever vga_update_text() or vga_draw_text() happens to be called first
only the text display or only the graphics display will see display
resolution changes and full redraws.

Fix it by calling both text/gfx resize functions in both code paths and
keep track of full screen redraws needed in VGACommonState fields.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vga.c     |   19 +++++++++++++++++++
 hw/vga_int.h |    2 ++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/vga.c b/hw/vga.c
index 19a68ff..a0ba94d 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1350,6 +1350,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
         s->last_scr_width = width * cw;
         s->last_scr_height = height * cheight;
         qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
+        dpy_text_resize(s->ds, width, height);
         s->last_depth = 0;
         s->last_width = width;
         s->last_height = height;
@@ -1363,6 +1364,14 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     palette = s->last_palette;
     x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
 
+    if (full_update) {
+        s->full_update_text = 1;
+    }
+    if (s->full_update_gfx) {
+        s->full_update_gfx = 0;
+        full_update |= 1;
+    }
+
     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
     if (cursor_offset != s->cursor_offset ||
@@ -2063,7 +2072,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             cw != s->last_cw || cheight != s->last_ch) {
             s->last_scr_width = width * cw;
             s->last_scr_height = height * cheight;
+            qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
             dpy_text_resize(s->ds, width, height);
+            s->last_depth = 0;
             s->last_width = width;
             s->last_height = height;
             s->last_ch = cheight;
@@ -2071,6 +2082,14 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             full_update = 1;
         }
 
+        if (full_update) {
+            s->full_update_gfx = 1;
+        }
+        if (s->full_update_text) {
+            s->full_update_text = 0;
+            full_update |= 1;
+        }
+
         /* Update "hardware" cursor */
         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 330a32f..713f53f 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -166,6 +166,8 @@ typedef struct VGACommonState {
     vga_hw_invalidate_ptr invalidate;
     vga_hw_screen_dump_ptr screen_dump;
     vga_hw_text_update_ptr text_update;
+    bool full_update_text;
+    bool full_update_gfx;
     /* hardware mouse cursor support */
     uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
     void (*cursor_invalidate)(struct VGACommonState *s);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 8/8] console: remove dpy_gfx_fill
  2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 7/8] vga: fix text mode updating Gerd Hoffmann
@ 2012-10-15  9:51 ` Gerd Hoffmann
  7 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2012-10-15  9:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Unused code.  'nuff said.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h |   13 -------------
 ui/sdl.c  |    7 -------
 2 files changed, 0 insertions(+), 20 deletions(-)

diff --git a/console.h b/console.h
index bd56f3c..78e842f 100644
--- a/console.h
+++ b/console.h
@@ -161,8 +161,6 @@ struct DisplayChangeListener {
     void (*dpy_gfx_setdata)(struct 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_gfx_fill)(struct DisplayState *s, int x, int y,
-                         int w, int h, uint32_t c);
 
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
     void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
@@ -306,17 +304,6 @@ static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
     }
 }
 
-static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
-                                int w, int h, uint32_t c)
-{
-    struct DisplayChangeListener *dcl;
-    QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_gfx_fill) {
-            dcl->dpy_gfx_fill(s, x, y, w, h, c);
-        }
-    }
-}
-
 static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
 {
     struct DisplayChangeListener *dcl;
diff --git a/ui/sdl.c b/ui/sdl.c
index fac1a47..c3ba79f 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -899,12 +899,6 @@ static void sdl_refresh(DisplayState *ds)
     }
 }
 
-static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
-{
-    SDL_Rect dst = { x, y, w, h };
-    SDL_FillRect(real_screen, &dst, c);
-}
-
 static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
 {
     if (on) {
@@ -1024,7 +1018,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     dcl->dpy_gfx_resize = sdl_resize;
     dcl->dpy_refresh = sdl_refresh;
     dcl->dpy_gfx_setdata = sdl_setdata;
-    dcl->dpy_gfx_fill = sdl_fill;
     dcl->dpy_mouse_set = sdl_mouse_warp;
     dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener
  2012-10-15  9:51 ` [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener Gerd Hoffmann
@ 2012-10-15 14:16   ` Andreas Färber
  0 siblings, 0 replies; 10+ messages in thread
From: Andreas Färber @ 2012-10-15 14:16 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Am 15.10.2012 11:51, schrieb Gerd Hoffmann:
> Also change the way the gui_timer is initialized: each time a
> displaychangelistener is registered or unregistered we'll check
> whenever we need a timer (due to dpy_refresh callback being present)

"whether"

> and if so setup a timer, otherwise zap it.  This way the gui timer works
> correctly with displaychangelisteners coming and going.
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Logic looks okay to me.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-10-15 14:17 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-15  9:51 [Qemu-devel] [PATCH 0/8] console cleanups Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 1/8] console: QLIST-ify display change listeners Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener Gerd Hoffmann
2012-10-15 14:16   ` Andreas Färber
2012-10-15  9:51 ` [Qemu-devel] [PATCH 3/8] console: move set_mouse + cursor_define callbacks Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 4/8] console: s/TextConsole/QemuConsole/ Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 5/8] console: untangle gfx & txt updates Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 6/8] console: init displaychangelisteners on register Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 7/8] vga: fix text mode updating Gerd Hoffmann
2012-10-15  9:51 ` [Qemu-devel] [PATCH 8/8] console: remove dpy_gfx_fill 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).