All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued
@ 2013-04-04  7:28 Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 01/24] exynos4210_fimd.c: fix display resize bug introduced after console revamp Gerd Hoffmann
                   ` (23 more replies)
  0 siblings, 24 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Next round of console cleanup patches for review.  What is in there?

  (1) qemu text consoles are rendered using pixman now.
  (2) Each QemuConsole has its own DisplaySurface now, so we can
      switch consoles without re-rendering the QemuConsole and
      update non-active consoles.
  (3) Based on (2) the screendump code is simplified *alot*.
  (4) gui refresh timer adaption is fixes and consolidated.

Also some cleanups and bugfixes.

v3 changes:
  * more bugfixes (especially vmware vga).
  * dropped multi-window gtk patch for now (needs some more
    refinement + discussions, but I don't want it block the
    other patches).
  * addressed v2 review comments.

v2 adds:
  * bugfixes from Igor.
  * multihead support.

cheers,
  Gerd

The following changes since commit 4dbb9ed3263e0f48282a2fc3d05099ba63e5b0e2:

  xilinx_axienet: pump events as appropriate (2013-04-04 00:55:03 +0200)

are available in the git repository at:

  git://git.kraxel.org/qemu pixman.v10

for you to fetch changes up to e98ffc5606e9aa294e04d214f9fa0e90b22a8ab0:

  qxl: register QemuConsole for secondary cards (2013-04-04 09:18:04 +0200)

----------------------------------------------------------------
Gerd Hoffmann (22):
      hw/vmware_vga.c: add tracepoints for mmio reads+writes
      hw/vmware_vga.c: various vmware vga fixes.
      pixman: add qemu_pixman_color()
      pixman: render vgafont glyphs into pixman images
      console: use pixman for fill+blit
      console: use pixman for font rendering
      console: switch color_table_rgb to pixman_color_t
      console: add trace events
      console: displaystate init revamp
      console: rename vga_hw_*, add QemuConsole param
      console: give each QemuConsole its own DisplaySurface
      console: simplify screendump
      console: zap g_width + g_height
      console: move gui_update+gui_setup_refresh from vl.c into console.c
      console: make DisplayState private to console.c
      console: add GraphicHwOps
      console: gui timer fixes
      xen: re-enable refresh interval reporting for xenfb
      console: add qemu_console_is_*
      console: allow pinning displaychangelisteners to consoles
      gtk: custom cursor support
      qxl: register QemuConsole for secondary cards

Igor Mitsyanko (2):
      exynos4210_fimd.c: fix display resize bug introduced after console revamp
      hw/vmware_vga.c: fix screen resize bug introduced after console revamp

 hw/arm/musicpal.c          |    8 +-
 hw/blizzard.c              |   21 +-
 hw/cirrus_vga.c            |   10 +-
 hw/exynos4210_fimd.c       |   15 +-
 hw/g364fb.c                |   80 +-----
 hw/jazz_led.c              |   11 +-
 hw/milkymist-vgafb.c       |    9 +-
 hw/omap_lcdc.c             |   93 +-----
 hw/pl110.c                 |    9 +-
 hw/pxa2xx_lcd.c            |    9 +-
 hw/qxl.c                   |   42 +--
 hw/sm501.c                 |    7 +-
 hw/ssd0303.c               |    9 +-
 hw/ssd0323.c               |    9 +-
 hw/tc6393xb.c              |   10 +-
 hw/tcx.c                   |  143 +---------
 hw/unicore32/puv3.c        |    4 +-
 hw/vga-isa-mm.c            |    4 +-
 hw/vga-isa.c               |    3 +-
 hw/vga-pci.c               |    3 +-
 hw/vga.c                   |   76 +----
 hw/vga_int.h               |    6 +-
 hw/vmware_vga.c            |  198 +++++++------
 hw/xenfb.c                 |   58 ++--
 include/ui/console.h       |   55 ++--
 include/ui/qemu-pixman.h   |    9 +
 include/ui/spice-display.h |    1 -
 trace-events               |   11 +
 ui/console.c               |  676 ++++++++++++++++++++++++--------------------
 ui/curses.c                |   11 +-
 ui/gtk.c                   |   36 ++-
 ui/qemu-pixman.c           |   54 ++++
 ui/sdl.c                   |   52 ++--
 ui/spice-display.c         |   11 +-
 ui/vnc.c                   |   87 ++----
 ui/vnc.h                   |    2 -
 vl.c                       |   55 +---
 37 files changed, 831 insertions(+), 1066 deletions(-)

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

* [Qemu-devel] [PATCH 01/24] exynos4210_fimd.c: fix display resize bug introduced after console revamp
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Mitsyanko, Evgeny Voevodin, Igor Mitsyanko, Gerd Hoffmann,
	Maksim Kozlov, Dmitry Solodkiy

From: Igor Mitsyanko <i.mitsyanko@gmail.com>

In exynos4210 display update function, we were acquiring DisplaySurface
pointer before calling screen resize function, not paying attention that resize
procedure can replace current DisplaySurface with newly allocated one.
Right thing to do is to initialize DisplaySurface AFTER a call to resize function.

Signed-off-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/exynos4210_fimd.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index bf316c6..333456a 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1243,7 +1243,7 @@ static void exynos4210_update_resolution(Exynos4210fimdState *s)
 static void exynos4210_fimd_update(void *opaque)
 {
     Exynos4210fimdState *s = (Exynos4210fimdState *)opaque;
-    DisplaySurface *surface = qemu_console_surface(s->console);
+    DisplaySurface *surface;
     Exynos4210fimdWindow *w;
     int i, line;
     hwaddr fb_line_addr, inc_size;
@@ -1256,11 +1256,12 @@ static void exynos4210_fimd_update(void *opaque)
     const int global_height = ((s->vidtcon[2] >> FIMD_VIDTCON2_VER_SHIFT) &
             FIMD_VIDTCON2_SIZE_MASK) + 1;
 
-    if (!s || !s->console || !surface_bits_per_pixel(surface) ||
-            !s->enabled) {
+    if (!s || !s->console || !s->enabled ||
+        surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
         return;
     }
     exynos4210_update_resolution(s);
+    surface = qemu_console_surface(s->console);
 
     for (i = 0; i < NUM_OF_WINDOWS; i++) {
         w = &s->window[i];
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen resize bug introduced after console revamp
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 01/24] exynos4210_fimd.c: fix display resize bug introduced after console revamp Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-05 11:21   ` Alexandru Damian
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 03/24] hw/vmware_vga.c: add tracepoints for mmio reads+writes Gerd Hoffmann
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Igor Mitsyanko, Gerd Hoffmann

From: Igor Mitsyanko <i.mitsyanko@gmail.com>

In vmsvga display update function, a pointer to DisplaySurface must be acquired
after a call to vmsvga_check_size since this function might replace current
DisplaySurface with a new one.

Signed-off-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vmware_vga.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5b9ce8f..c0aac31 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -995,7 +995,7 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s)
 static void vmsvga_update_display(void *opaque)
 {
     struct vmsvga_state_s *s = opaque;
-    DisplaySurface *surface = qemu_console_surface(s->vga.con);
+    DisplaySurface *surface;
     bool dirty = false;
 
     if (!s->enable) {
@@ -1004,6 +1004,7 @@ static void vmsvga_update_display(void *opaque)
     }
 
     vmsvga_check_size(s);
+    surface = qemu_console_surface(s->vga.con);
 
     vmsvga_fifo_run(s);
     vmsvga_update_rect_flush(s);
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 03/24] hw/vmware_vga.c: add tracepoints for mmio reads+writes
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 01/24] exynos4210_fimd.c: fix display resize bug introduced after console revamp Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 04/24] hw/vmware_vga.c: various vmware vga fixes Gerd Hoffmann
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vmware_vga.c |  112 +++++++++++++++++++++++++++++++++++++++----------------
 trace-events    |    6 +++
 2 files changed, 86 insertions(+), 32 deletions(-)

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index c0aac31..2dfab75 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -721,61 +721,79 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
     uint32_t caps;
     struct vmsvga_state_s *s = opaque;
     DisplaySurface *surface = qemu_console_surface(s->vga.con);
+    uint32_t ret;
 
     switch (s->index) {
     case SVGA_REG_ID:
-        return s->svgaid;
+        ret = s->svgaid;
+        break;
 
     case SVGA_REG_ENABLE:
-        return s->enable;
+        ret = s->enable;
+        break;
 
     case SVGA_REG_WIDTH:
-        return surface_width(surface);
+        ret = surface_width(surface);
+        break;
 
     case SVGA_REG_HEIGHT:
-        return surface_height(surface);
+        ret = surface_height(surface);
+        break;
 
     case SVGA_REG_MAX_WIDTH:
-        return SVGA_MAX_WIDTH;
+        ret = SVGA_MAX_WIDTH;
+        break;
 
     case SVGA_REG_MAX_HEIGHT:
-        return SVGA_MAX_HEIGHT;
+        ret = SVGA_MAX_HEIGHT;
+        break;
 
     case SVGA_REG_DEPTH:
-        return s->depth;
+        ret = s->depth;
+        break;
 
     case SVGA_REG_BITS_PER_PIXEL:
-        return (s->depth + 7) & ~7;
+        ret = (s->depth + 7) & ~7;
+        break;
 
     case SVGA_REG_PSEUDOCOLOR:
-        return 0x0;
+        ret = 0x0;
+        break;
 
     case SVGA_REG_RED_MASK:
-        return surface->pf.rmask;
+        ret = surface->pf.rmask;
+        break;
 
     case SVGA_REG_GREEN_MASK:
-        return surface->pf.gmask;
+        ret = surface->pf.gmask;
+        break;
 
     case SVGA_REG_BLUE_MASK:
-        return surface->pf.bmask;
+        ret = surface->pf.bmask;
+        break;
 
     case SVGA_REG_BYTES_PER_LINE:
-        return s->bypp * s->new_width;
+        ret = s->bypp * s->new_width;
+        break;
 
     case SVGA_REG_FB_START: {
         struct pci_vmsvga_state_s *pci_vmsvga
             = container_of(s, struct pci_vmsvga_state_s, chip);
-        return pci_get_bar_addr(&pci_vmsvga->card, 1);
+        ret = pci_get_bar_addr(&pci_vmsvga->card, 1);
+        break;
     }
 
     case SVGA_REG_FB_OFFSET:
-        return 0x0;
+        ret = 0x0;
+        break;
 
     case SVGA_REG_VRAM_SIZE:
-        return s->vga.vram_size; /* No physical VRAM besides the framebuffer */
+        ret = s->vga.vram_size; /* No physical VRAM besides the framebuffer */
+        break;
 
     case SVGA_REG_FB_SIZE:
-        return s->vga.vram_size;
+        ret = s->vga.vram_size;
+        break;
 
     case SVGA_REG_CAPABILITIES:
         caps = SVGA_CAP_NONE;
@@ -791,66 +809,96 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
                     SVGA_CAP_CURSOR_BYPASS;
         }
 #endif
-        return caps;
+        ret = caps;
+        break;
 
     case SVGA_REG_MEM_START: {
         struct pci_vmsvga_state_s *pci_vmsvga
             = container_of(s, struct pci_vmsvga_state_s, chip);
-        return pci_get_bar_addr(&pci_vmsvga->card, 2);
+        ret = pci_get_bar_addr(&pci_vmsvga->card, 2);
+        break;
     }
 
     case SVGA_REG_MEM_SIZE:
-        return s->fifo_size;
+        ret = s->fifo_size;
+        break;
 
     case SVGA_REG_CONFIG_DONE:
-        return s->config;
+        ret = s->config;
+        break;
 
     case SVGA_REG_SYNC:
     case SVGA_REG_BUSY:
-        return s->syncing;
+        ret = s->syncing;
+        break;
 
     case SVGA_REG_GUEST_ID:
-        return s->guest;
+        ret = s->guest;
+        break;
 
     case SVGA_REG_CURSOR_ID:
-        return s->cursor.id;
+        ret = s->cursor.id;
+        break;
 
     case SVGA_REG_CURSOR_X:
-        return s->cursor.x;
+        ret = s->cursor.x;
+        break;
 
     case SVGA_REG_CURSOR_Y:
-        return s->cursor.x;
+        ret = s->cursor.x;
+        break;
 
     case SVGA_REG_CURSOR_ON:
-        return s->cursor.on;
+        ret = s->cursor.on;
+        break;
 
     case SVGA_REG_HOST_BITS_PER_PIXEL:
-        return (s->depth + 7) & ~7;
+        ret = (s->depth + 7) & ~7;
+        break;
 
     case SVGA_REG_SCRATCH_SIZE:
-        return s->scratch_size;
+        ret = s->scratch_size;
+        break;
 
     case SVGA_REG_MEM_REGS:
     case SVGA_REG_NUM_DISPLAYS:
     case SVGA_REG_PITCHLOCK:
     case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:
-        return 0;
+        ret = 0;
+        break;
 
     default:
         if (s->index >= SVGA_SCRATCH_BASE &&
             s->index < SVGA_SCRATCH_BASE + s->scratch_size) {
-            return s->scratch[s->index - SVGA_SCRATCH_BASE];
+            ret = s->scratch[s->index - SVGA_SCRATCH_BASE];
+            break;
         }
         printf("%s: Bad register %02x\n", __func__, s->index);
+        ret = 0;
+        break;
     }
 
-    return 0;
+    if (s->index >= SVGA_SCRATCH_BASE) {
+        trace_vmware_scratch_read(s->index, ret);
+    } else if (s->index >= SVGA_PALETTE_BASE) {
+        trace_vmware_palette_read(s->index, ret);
+    } else {
+        trace_vmware_value_read(s->index, ret);
+    }
+    return ret;
 }
 
 static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
 {
     struct vmsvga_state_s *s = opaque;
 
+    if (s->index >= SVGA_SCRATCH_BASE) {
+        trace_vmware_scratch_write(s->index, value);
+    } else if (s->index >= SVGA_PALETTE_BASE) {
+        trace_vmware_palette_write(s->index, value);
+    } else {
+        trace_vmware_value_write(s->index, value);
+    }
     switch (s->index) {
     case SVGA_REG_ID:
         if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) {
diff --git a/trace-events b/trace-events
index 7f34112..030ab70 100644
--- a/trace-events
+++ b/trace-events
@@ -969,6 +969,12 @@ displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
 
 # vga.c
 ppm_save(const char *filename, void *display_surface) "%s surface=%p"
+vmware_value_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_value_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_palette_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_palette_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
 
 # savevm.c
 
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 04/24] hw/vmware_vga.c: various vmware vga fixes.
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 03/24] hw/vmware_vga.c: add tracepoints for mmio reads+writes Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 05/24] pixman: add qemu_pixman_color() Gerd Hoffmann
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Hardcode depth to 32 bpp.  It effectively was that way before because
that is the default surface depth, this just makes it explicit in the
code.

Rename depth to new_depth to make it consistent with the new_width +
new_height names.  In theory we can make new_depth changeable (i.e.
allow the guest to fill in -- say -- 16 there).  In practice the guests
don't try, the X-Server refuses to start if you ask it to use 16bpp
depth (via DefaultDepth in the Screen section).

Always return the correct rmask+gmask+bmask values for the given
new_depth.

Fix mode setting to also verify at new_depth to make sure we have a
correct DisplaySurface, even if the current video mode happes to be
16bpp (set by vgabios via bochs vbe interface).  While being at it
switch over to use qemu_create_displaysurface_from, so the surface is
backed by guest-visible video memory and we save a memcpy.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vmware_vga.c |   57 +++++++++++++++++++++++++++++--------------------------
 trace-events    |    1 +
 2 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 2dfab75..0d9a584 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -39,8 +39,6 @@ struct vmsvga_state_s {
     VGACommonState vga;
 
     int invalidated;
-    int depth;
-    int bypp;
     int enable;
     int config;
     struct {
@@ -55,6 +53,7 @@ struct vmsvga_state_s {
     uint32_t *scratch;
     int new_width;
     int new_height;
+    int new_depth;
     uint32_t guest;
     uint32_t svgaid;
     int syncing;
@@ -721,6 +720,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
     uint32_t caps;
     struct vmsvga_state_s *s = opaque;
     DisplaySurface *surface = qemu_console_surface(s->vga.con);
+    PixelFormat pf;
     uint32_t ret;
 
     switch (s->index) {
@@ -733,11 +733,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
         break;
 
     case SVGA_REG_WIDTH:
-        ret = surface_width(surface);
+        ret = s->new_width ? s->new_width : surface_width(surface);
         break;
 
     case SVGA_REG_HEIGHT:
-        ret = surface_height(surface);
+        ret = s->new_height ? s->new_height : surface_height(surface);
         break;
 
     case SVGA_REG_MAX_WIDTH:
@@ -749,11 +749,12 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
         break;
 
     case SVGA_REG_DEPTH:
-        ret = s->depth;
+        ret = (s->new_depth == 32) ? 24 : s->new_depth;
         break;
 
     case SVGA_REG_BITS_PER_PIXEL:
-        ret = (s->depth + 7) & ~7;
+    case SVGA_REG_HOST_BITS_PER_PIXEL:
+        ret = s->new_depth;
         break;
 
     case SVGA_REG_PSEUDOCOLOR:
@@ -761,19 +762,26 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
         break;
 
     case SVGA_REG_RED_MASK:
-        ret = surface->pf.rmask;
+        pf = qemu_default_pixelformat(s->new_depth);
+        ret = pf.rmask;
         break;
 
     case SVGA_REG_GREEN_MASK:
-        ret = surface->pf.gmask;
+        pf = qemu_default_pixelformat(s->new_depth);
+        ret = pf.gmask;
         break;
 
     case SVGA_REG_BLUE_MASK:
-        ret = surface->pf.bmask;
+        pf = qemu_default_pixelformat(s->new_depth);
+        ret = pf.bmask;
         break;
 
     case SVGA_REG_BYTES_PER_LINE:
-        ret = s->bypp * s->new_width;
+        if (s->new_width) {
+            ret = (s->new_depth * s->new_width) / 8;
+        } else {
+            ret = surface_stride(surface);
+        }
         break;
 
     case SVGA_REG_FB_START: {
@@ -852,10 +860,6 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
         ret = s->cursor.on;
         break;
 
-    case SVGA_REG_HOST_BITS_PER_PIXEL:
-        ret = (s->depth + 7) & ~7;
-        break;
-
     case SVGA_REG_SCRATCH_SIZE:
         ret = s->scratch_size;
         break;
@@ -936,9 +940,10 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
         break;
 
     case SVGA_REG_BITS_PER_PIXEL:
-        if (value != s->depth) {
+        if (value != 32) {
             printf("%s: Bad bits per pixel: %i bits\n", __func__, value);
             s->config = 0;
+            s->invalidated = 1;
         }
         break;
 
@@ -1034,8 +1039,14 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s)
     DisplaySurface *surface = qemu_console_surface(s->vga.con);
 
     if (s->new_width != surface_width(surface) ||
-        s->new_height != surface_height(surface)) {
-        qemu_console_resize(s->vga.con, s->new_width, s->new_height);
+        s->new_height != surface_height(surface) ||
+        s->new_depth != surface_bits_per_pixel(surface)) {
+        int stride = (s->new_depth * s->new_width) / 8;
+        trace_vmware_setmode(s->new_width, s->new_height, s->new_depth);
+        surface = qemu_create_displaysurface_from(s->new_width, s->new_height,
+                                                  s->new_depth, stride,
+                                                  s->vga.vram_ptr, false);
+        dpy_gfx_replace_surface(s->vga.con, surface);
         s->invalidated = 1;
     }
 }
@@ -1069,8 +1080,6 @@ static void vmsvga_update_display(void *opaque)
     }
     if (s->invalidated || dirty) {
         s->invalidated = 0;
-        memcpy(surface_data(surface), s->vga.vram_ptr,
-               surface_stride(surface) * surface_height(surface));
         dpy_gfx_update(s->vga.con, 0, 0,
                    surface_width(surface), surface_height(surface));
     }
@@ -1162,7 +1171,7 @@ static const VMStateDescription vmstate_vmware_vga_internal = {
     .minimum_version_id_old = 0,
     .post_load = vmsvga_post_load,
     .fields      = (VMStateField[]) {
-        VMSTATE_INT32_EQUAL(depth, struct vmsvga_state_s),
+        VMSTATE_INT32_EQUAL(new_depth, struct vmsvga_state_s),
         VMSTATE_INT32(enable, struct vmsvga_state_s),
         VMSTATE_INT32(config, struct vmsvga_state_s),
         VMSTATE_INT32(cursor.id, struct vmsvga_state_s),
@@ -1198,8 +1207,6 @@ static const VMStateDescription vmstate_vmware_vga = {
 static void vmsvga_init(struct vmsvga_state_s *s,
                         MemoryRegion *address_space, MemoryRegion *io)
 {
-    DisplaySurface *surface;
-
     s->scratch_size = SVGA_SCRATCH_SIZE;
     s->scratch = g_malloc(s->scratch_size * 4);
 
@@ -1207,7 +1214,6 @@ static void vmsvga_init(struct vmsvga_state_s *s,
                                       vmsvga_invalidate_display,
                                       vmsvga_screen_dump,
                                       vmsvga_text_update, s);
-    surface = qemu_console_surface(s->vga.con);
 
     s->fifo_size = SVGA_FIFO_SIZE;
     memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size);
@@ -1217,10 +1223,7 @@ static void vmsvga_init(struct vmsvga_state_s *s,
     vga_common_init(&s->vga);
     vga_init(&s->vga, address_space, io, true);
     vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
-    /* Save some values here in case they are changed later.
-     * This is suspicious and needs more though why it is needed. */
-    s->depth = surface_bits_per_pixel(surface);
-    s->bypp = surface_bytes_per_pixel(surface);
+    s->new_depth = 32;
 }
 
 static uint64_t vmsvga_io_read(void *opaque, hwaddr addr, unsigned size)
diff --git a/trace-events b/trace-events
index 030ab70..ad863ec 100644
--- a/trace-events
+++ b/trace-events
@@ -975,6 +975,7 @@ vmware_palette_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
 vmware_palette_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
 vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
 vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
+vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
 
 # savevm.c
 
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 05/24] pixman: add qemu_pixman_color()
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 04/24] hw/vmware_vga.c: various vmware vga fixes Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 06/24] pixman: render vgafont glyphs into pixman images Gerd Hoffmann
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Helper function to map qemu colors (32bit integer + matching PixelFormat)
into pixman_color_t.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/qemu-pixman.h |    2 ++
 ui/qemu-pixman.c         |   11 +++++++++++
 2 files changed, 13 insertions(+)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index b032f52..b0f09b5 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -43,4 +43,6 @@ pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
                                           pixman_image_t *image);
 void qemu_pixman_image_unref(pixman_image_t *image);
 
+pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color);
+
 #endif /* QEMU_PIXMAN_H */
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 6dcbe90..be551e0 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -79,3 +79,14 @@ void qemu_pixman_image_unref(pixman_image_t *image)
     }
     pixman_image_unref(image);
 }
+
+pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color)
+{
+    pixman_color_t c;
+
+    c.red   = ((color & pf->rmask) >> pf->rshift) << (16 - pf->rbits);
+    c.green = ((color & pf->gmask) >> pf->gshift) << (16 - pf->gbits);
+    c.blue  = ((color & pf->bmask) >> pf->bshift) << (16 - pf->bbits);
+    c.alpha = ((color & pf->amask) >> pf->ashift) << (16 - pf->abits);
+    return c;
+}
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 06/24] pixman: render vgafont glyphs into pixman images
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 05/24] pixman: add qemu_pixman_color() Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 07/24] console: use pixman for fill+blit Gerd Hoffmann
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Add helper functions to create pixman mask images for glyphs
and to render these glyphs into a pixman image.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/qemu-pixman.h |    7 +++++++
 ui/qemu-pixman.c         |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index b0f09b5..f012ec5 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -44,5 +44,12 @@ pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
 void qemu_pixman_image_unref(pixman_image_t *image);
 
 pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color);
+pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
+                                               unsigned int ch);
+void qemu_pixman_glyph_render(pixman_image_t *glyph,
+                              pixman_image_t *surface,
+                              pixman_color_t *fgcol,
+                              pixman_color_t *bgcol,
+                              int x, int y, int cw, int ch);
 
 #endif /* QEMU_PIXMAN_H */
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index be551e0..254bd8c 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -90,3 +90,46 @@ pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color)
     c.alpha = ((color & pf->amask) >> pf->ashift) << (16 - pf->abits);
     return c;
 }
+
+pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
+                                               unsigned int ch)
+{
+    pixman_image_t *glyph;
+    uint8_t *data;
+    bool bit;
+    int x, y;
+
+    glyph = pixman_image_create_bits(PIXMAN_a8, 8, height,
+                                     NULL, 0);
+    data = (uint8_t *)pixman_image_get_data(glyph);
+
+    font += height * ch;
+    for (y = 0; y < height; y++, font++) {
+        for (x = 0; x < 8; x++, data++) {
+            bit = (*font) & (1 << (7-x));
+            *data = bit ? 0xff : 0x00;
+        }
+    }
+    return glyph;
+}
+
+void qemu_pixman_glyph_render(pixman_image_t *glyph,
+                              pixman_image_t *surface,
+                              pixman_color_t *fgcol,
+                              pixman_color_t *bgcol,
+                              int x, int y, int cw, int ch)
+{
+    pixman_image_t *ifg = pixman_image_create_solid_fill(fgcol);
+    pixman_image_t *ibg = pixman_image_create_solid_fill(bgcol);
+
+    pixman_image_composite(PIXMAN_OP_SRC, ibg, NULL, surface,
+                           0, 0, 0, 0,
+                           cw * x, ch * y,
+                           cw, ch);
+    pixman_image_composite(PIXMAN_OP_OVER, ifg, glyph, surface,
+                           0, 0, 0, 0,
+                           cw * x, ch * y,
+                           cw, ch);
+    pixman_image_unref(ifg);
+    pixman_image_unref(ibg);
+}
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 07/24] console: use pixman for fill+blit
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 06/24] pixman: render vgafont glyphs into pixman images Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 08/24] console: use pixman for font rendering Gerd Hoffmann
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Zap homegrown pixel shuffeling code, use pixman calls instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c |   65 +++++++++-------------------------------------------------
 1 file changed, 10 insertions(+), 55 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index e84ba8b..b641c35 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -213,36 +213,14 @@ static void vga_fill_rect(QemuConsole *con,
                           uint32_t color)
 {
     DisplaySurface *surface = qemu_console_surface(con);
-    uint8_t *d, *d1;
-    int x, y, bpp;
+    pixman_rectangle16_t rect = {
+        .x = posx, .y = posy, .width = width, .height = height
+    };
+    pixman_color_t pcolor;
 
-    bpp = surface_bytes_per_pixel(surface);
-    d1 = surface_data(surface) +
-        surface_stride(surface) * posy + bpp * posx;
-    for (y = 0; y < height; y++) {
-        d = d1;
-        switch(bpp) {
-        case 1:
-            for (x = 0; x < width; x++) {
-                *((uint8_t *)d) = color;
-                d++;
-            }
-            break;
-        case 2:
-            for (x = 0; x < width; x++) {
-                *((uint16_t *)d) = color;
-                d += 2;
-            }
-            break;
-        case 4:
-            for (x = 0; x < width; x++) {
-                *((uint32_t *)d) = color;
-                d += 4;
-            }
-            break;
-        }
-        d1 += surface_stride(surface);
-    }
+    pcolor = qemu_pixman_color(&surface->pf, color);
+    pixman_image_fill_rectangles(PIXMAN_OP_SRC, surface->image,
+                                 &pcolor, 1, &rect);
 }
 
 /* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
@@ -250,33 +228,10 @@ static void vga_bitblt(QemuConsole *con,
                        int xs, int ys, int xd, int yd, int w, int h)
 {
     DisplaySurface *surface = qemu_console_surface(con);
-    const uint8_t *s;
-    uint8_t *d;
-    int wb, y, bpp;
 
-    bpp = surface_bytes_per_pixel(surface);
-    wb = w * bpp;
-    if (yd <= ys) {
-        s = surface_data(surface) +
-            surface_stride(surface) * ys + bpp * xs;
-        d = surface_data(surface) +
-            surface_stride(surface) * yd + bpp * xd;
-        for (y = 0; y < h; y++) {
-            memmove(d, s, wb);
-            d += surface_stride(surface);
-            s += surface_stride(surface);
-        }
-    } else {
-        s = surface_data(surface) +
-            surface_stride(surface) * (ys + h - 1) + bpp * xs;
-        d = surface_data(surface) +
-            surface_stride(surface) * (yd + h - 1) + bpp * xd;
-       for (y = 0; y < h; y++) {
-            memmove(d, s, wb);
-            d -= surface_stride(surface);
-            s -= surface_stride(surface);
-        }
-    }
+    pixman_image_composite(PIXMAN_OP_SRC,
+                           surface->image, NULL, surface->image,
+                           xs, ys, 0, 0, xd, yd, w, h);
 }
 
 /***********************************************************/
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 08/24] console: use pixman for font rendering
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 07/24] console: use pixman for fill+blit Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 09/24] console: switch color_table_rgb to pixman_color_t Gerd Hoffmann
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Zap homegrown font rendering code, use pixman calls instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c |  110 ++++++----------------------------------------------------
 1 file changed, 11 insertions(+), 99 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index b641c35..e2a4535 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -242,45 +242,6 @@ static void vga_bitblt(QemuConsole *con,
 
 #include "vgafont.h"
 
-#define cbswap_32(__x) \
-((uint32_t)( \
-		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
-		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
-		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
-		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define PAT(x) x
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
-    PAT(0x00000000),
-    PAT(0x000000ff),
-    PAT(0x0000ff00),
-    PAT(0x0000ffff),
-    PAT(0x00ff0000),
-    PAT(0x00ff00ff),
-    PAT(0x00ffff00),
-    PAT(0x00ffffff),
-    PAT(0xff000000),
-    PAT(0xff0000ff),
-    PAT(0xff00ff00),
-    PAT(0xff00ffff),
-    PAT(0xffff0000),
-    PAT(0xffff00ff),
-    PAT(0xffffff00),
-    PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
-    PAT(0x00000000),
-    PAT(0x0000ffff),
-    PAT(0xffff0000),
-    PAT(0xffffffff),
-};
-
 #ifndef CONFIG_CURSES
 enum color_names {
     COLOR_BLACK   = 0,
@@ -353,17 +314,11 @@ static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
 static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
                           TextAttributes *t_attrib)
 {
+    static pixman_image_t *glyphs[256];
     DisplaySurface *surface = qemu_console_surface(s);
-    uint8_t *d;
-    const uint8_t *font_ptr;
-    unsigned int font_data, linesize, xorcol, bpp;
-    int i;
     unsigned int fgcol, bgcol;
-
-#ifdef DEBUG_CONSOLE
-    printf("x: %2i y: %2i", x, y);
-    console_print_text_attributes(t_attrib, ch);
-#endif
+    pixman_image_t *ifg, *ibg;
+    pixman_color_t cfg, cbg;
 
     if (t_attrib->invers) {
         bgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
@@ -372,59 +327,16 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
         fgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
         bgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
     }
+    cfg = qemu_pixman_color(&surface->pf, fgcol);
+    cbg = qemu_pixman_color(&surface->pf, bgcol);
+    ifg = pixman_image_create_solid_fill(&cfg);
+    ibg = pixman_image_create_solid_fill(&cbg);
 
-    bpp = surface_bytes_per_pixel(surface);
-    d = surface_data(surface) +
-        surface_stride(surface) * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
-    linesize = surface_stride(surface);
-    font_ptr = vgafont16 + FONT_HEIGHT * ch;
-    xorcol = bgcol ^ fgcol;
-    switch (surface_bits_per_pixel(surface)) {
-    case 8:
-        for(i = 0; i < FONT_HEIGHT; i++) {
-            font_data = *font_ptr++;
-            if (t_attrib->uline
-                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
-                font_data = 0xFF;
-            }
-            ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
-            ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
-            d += linesize;
-        }
-        break;
-    case 16:
-    case 15:
-        for(i = 0; i < FONT_HEIGHT; i++) {
-            font_data = *font_ptr++;
-            if (t_attrib->uline
-                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
-                font_data = 0xFF;
-            }
-            ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
-            ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
-            ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
-            ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
-            d += linesize;
-        }
-        break;
-    case 32:
-        for(i = 0; i < FONT_HEIGHT; i++) {
-            font_data = *font_ptr++;
-            if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
-                font_data = 0xFF;
-            }
-            ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
-            ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
-            d += linesize;
-        }
-        break;
+    if (!glyphs[ch]) {
+        glyphs[ch] = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, ch);
     }
+    qemu_pixman_glyph_render(glyphs[ch], surface->image,
+                             &cfg, &cbg, x, y, FONT_WIDTH, FONT_HEIGHT);
 }
 
 static void text_console_resize(QemuConsole *s)
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 09/24] console: switch color_table_rgb to pixman_color_t
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 08/24] console: use pixman for font rendering Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 10/24] console: add trace events Gerd Hoffmann
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Now that all text console rendering uses pixman we can easily
switch the color tables to use pixman_color_t directly.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c |   24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index e2a4535..41005c1 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -32,9 +32,6 @@
 #define MAX_CONSOLES 12
 #define CONSOLE_CURSOR_PERIOD 500
 
-#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
-
 typedef struct TextAttributes {
     uint8_t fgcol:4;
     uint8_t bgcol:4;
@@ -210,17 +207,15 @@ void vga_hw_text_update(console_ch_t *chardata)
 
 static void vga_fill_rect(QemuConsole *con,
                           int posx, int posy, int width, int height,
-                          uint32_t color)
+                          pixman_color_t color)
 {
     DisplaySurface *surface = qemu_console_surface(con);
     pixman_rectangle16_t rect = {
         .x = posx, .y = posy, .width = width, .height = height
     };
-    pixman_color_t pcolor;
 
-    pcolor = qemu_pixman_color(&surface->pf, color);
     pixman_image_fill_rectangles(PIXMAN_OP_SRC, surface->image,
-                                 &pcolor, 1, &rect);
+                                 &color, 1, &rect);
 }
 
 /* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
@@ -255,7 +250,10 @@ enum color_names {
 };
 #endif
 
-static const uint32_t color_table_rgb[2][8] = {
+#define QEMU_RGB(r, g, b)                                               \
+    { .red = r << 8, .green = g << 8, .blue = b << 8, .alpha = 0xffff }
+
+static const pixman_color_t color_table_rgb[2][8] = {
     {   /* dark */
         QEMU_RGB(0x00, 0x00, 0x00),  /* black */
         QEMU_RGB(0xaa, 0x00, 0x00),  /* red */
@@ -316,9 +314,7 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
 {
     static pixman_image_t *glyphs[256];
     DisplaySurface *surface = qemu_console_surface(s);
-    unsigned int fgcol, bgcol;
-    pixman_image_t *ifg, *ibg;
-    pixman_color_t cfg, cbg;
+    pixman_color_t fgcol, bgcol;
 
     if (t_attrib->invers) {
         bgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
@@ -327,16 +323,12 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
         fgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
         bgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
     }
-    cfg = qemu_pixman_color(&surface->pf, fgcol);
-    cbg = qemu_pixman_color(&surface->pf, bgcol);
-    ifg = pixman_image_create_solid_fill(&cfg);
-    ibg = pixman_image_create_solid_fill(&cbg);
 
     if (!glyphs[ch]) {
         glyphs[ch] = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, ch);
     }
     qemu_pixman_glyph_render(glyphs[ch], surface->image,
-                             &cfg, &cbg, x, y, FONT_WIDTH, FONT_HEIGHT);
+                             &fgcol, &bgcol, x, y, FONT_WIDTH, FONT_HEIGHT);
 }
 
 static void text_console_resize(QemuConsole *s)
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 10/24] console: add trace events
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 09/24] console: switch color_table_rgb to pixman_color_t Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 11/24] console: displaystate init revamp Gerd Hoffmann
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 trace-events |    3 +++
 ui/console.c |    4 ++++
 2 files changed, 7 insertions(+)

diff --git a/trace-events b/trace-events
index ad863ec..df60a93 100644
--- a/trace-events
+++ b/trace-events
@@ -961,6 +961,9 @@ dma_bdrv_cb(void *dbs, int ret) "dbs=%p ret=%d"
 dma_map_wait(void *dbs) "dbs=%p"
 
 # console.h
+console_gfx_new(void) ""
+console_txt_new(int w, int h) "%dx%d"
+console_select(int nr) "%d"
 displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
 displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
 displaysurface_free(void *display_surface) "surface=%p"
diff --git a/ui/console.c b/ui/console.c
index 41005c1..a4c9151 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -904,6 +904,8 @@ void console_select(unsigned int index)
 
     if (index >= MAX_CONSOLES)
         return;
+
+    trace_console_select(index);
     if (active_console) {
         surface = qemu_console_surface(active_console);
         active_console->g_width = surface_width(surface);
@@ -1367,6 +1369,7 @@ QemuConsole *graphic_console_init(vga_hw_update_ptr update,
     DisplayState *ds;
 
     ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
+    trace_console_gfx_new();
     s = new_console(ds, GRAPHIC_CONSOLE);
     s->hw_update = update;
     s->hw_invalidate = invalidate;
@@ -1485,6 +1488,7 @@ static CharDriverState *text_console_init(ChardevVC *vc)
         height = vc->rows * FONT_HEIGHT;
     }
 
+    trace_console_txt_new(width, height);
     if (width == 0 || height == 0) {
         s = new_console(NULL, TEXT_CONSOLE);
     } else {
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 11/24] console: displaystate init revamp
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 10/24] console: add trace events Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 12/24] console: rename vga_hw_*, add QemuConsole param Gerd Hoffmann
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

We have only one DisplayState, so there is no need for the "next"
linking, rip it.  Also consolidate all displaystate initialization
into init_displaystate().  This function is called by vl.c after
creating the devices (and thus all QemuConsoles) and before
initializing DisplayChangeListensers (aka gtk/sdl/vnc/spice ui).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |    5 +---
 ui/console.c         |   73 +++++++++++++++++++++++---------------------------
 vl.c                 |    6 +----
 3 files changed, 36 insertions(+), 48 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index a234c72..3725dae 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -189,12 +189,9 @@ struct DisplayState {
     bool have_text;
 
     QLIST_HEAD(, DisplayChangeListener) listeners;
-
-    struct DisplayState *next;
 };
 
-void register_displaystate(DisplayState *ds);
-DisplayState *get_displaystate(void);
+DisplayState *init_displaystate(void);
 DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data,
                                                 bool byteswap);
diff --git a/ui/console.c b/ui/console.c
index a4c9151..29f1805 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -163,6 +163,8 @@ static QemuConsole *active_console;
 static QemuConsole *consoles[MAX_CONSOLES];
 static int nb_consoles = 0;
 
+static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
+
 void vga_hw_update(void)
 {
     if (active_console && active_console->hw_update)
@@ -1323,39 +1325,37 @@ bool dpy_cursor_define_supported(QemuConsole *con)
     return false;
 }
 
-static void dumb_display_init(void)
-{
-    DisplayState *ds = g_malloc0(sizeof(DisplayState));
-    int width = 640;
-    int height = 480;
-
-    if (is_fixedsize_console()) {
-        width = active_console->g_width;
-        height = active_console->g_height;
-    }
-    ds->surface = qemu_create_displaysurface(width, height);
-
-    register_displaystate(ds);
-}
-
 /***********************************************************/
 /* register display */
 
-void register_displaystate(DisplayState *ds)
+/* console.c internal use only */
+static DisplayState *get_alloc_displaystate(void)
 {
-    DisplayState **s;
-    s = &display_state;
-    while (*s != NULL)
-        s = &(*s)->next;
-    ds->next = NULL;
-    *s = ds;
+    if (!display_state) {
+        display_state = g_new0(DisplayState, 1);
+    }
+    return display_state;
 }
 
-DisplayState *get_displaystate(void)
+/*
+ * Called by main(), after creating QemuConsoles
+ * and before initializing ui (sdl/vnc/...).
+ */
+DisplayState *init_displaystate(void)
 {
+    int i;
+
     if (!display_state) {
-        dumb_display_init ();
+        display_state = g_new0(DisplayState, 1);
     }
+
+    for (i = 0; i < nb_consoles; i++) {
+        if (consoles[i]->console_type != GRAPHIC_CONSOLE &&
+            consoles[i]->ds == NULL) {
+            text_console_do_init(consoles[i]->chr, display_state);
+        }
+    }
+
     return display_state;
 }
 
@@ -1365,10 +1365,12 @@ QemuConsole *graphic_console_init(vga_hw_update_ptr update,
                                   vga_hw_text_update_ptr text_update,
                                   void *opaque)
 {
+    int width = 640;
+    int height = 480;
     QemuConsole *s;
     DisplayState *ds;
 
-    ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
+    ds = get_alloc_displaystate();
     trace_console_gfx_new();
     s = new_console(ds, GRAPHIC_CONSOLE);
     s->hw_update = update;
@@ -1377,9 +1379,9 @@ QemuConsole *graphic_console_init(vga_hw_update_ptr update,
     s->hw_text_update = text_update;
     s->hw = opaque;
 
-    ds->surface = qemu_create_displaysurface(640, 480);
-
-    register_displaystate(ds);
+    if (!ds->surface) {
+        ds->surface = qemu_create_displaysurface(width, height);
+    }
     return s;
 }
 
@@ -1505,6 +1507,10 @@ static CharDriverState *text_console_init(ChardevVC *vc)
     s->g_height = height;
     chr->opaque = s;
     chr->chr_set_echo = text_console_set_echo;
+
+    if (display_state) {
+        text_console_do_init(chr, display_state);
+    }
     return chr;
 }
 
@@ -1520,17 +1526,6 @@ void register_vc_handler(VcHandler *handler)
     vc_handler = handler;
 }
 
-void text_consoles_set_display(DisplayState *ds)
-{
-    int i;
-
-    for (i = 0; i < nb_consoles; i++) {
-        if (consoles[i]->console_type != GRAPHIC_CONSOLE) {
-            text_console_do_init(consoles[i]->chr, ds);
-        }
-    }
-}
-
 void qemu_console_resize(QemuConsole *s, int width, int height)
 {
     s->g_width = width;
diff --git a/vl.c b/vl.c
index e2c9706..b05c289 100644
--- a/vl.c
+++ b/vl.c
@@ -4328,8 +4328,7 @@ int main(int argc, char **argv, char **envp)
 
     net_check_clients();
 
-    /* just use the first displaystate for the moment */
-    ds = get_displaystate();
+    ds = init_displaystate();
 
     /* init local displays */
     switch (display_type) {
@@ -4385,9 +4384,6 @@ int main(int argc, char **argv, char **envp)
     }
 #endif
 
-    /* display setup */
-    text_consoles_set_display(ds);
-
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
         exit(1);
     }
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 12/24] console: rename vga_hw_*, add QemuConsole param
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 11/24] console: displaystate init revamp Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 13/24] console: give each QemuConsole its own DisplaySurface Gerd Hoffmann
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Add QemuConsole parameter to vga_hw_*, so the interface allows to update
non-active consoles (the actual code can't handle this yet, see next
patch).  Passing NULL is allowed and updates the active console, like
the functions do today.

While touching all vga_hw_* calls anyway rename that to the functions to
hardware-neutral graphics_hw_*

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/cirrus_vga.c      |    2 +-
 hw/qxl.c             |    2 +-
 hw/vga.c             |    2 +-
 hw/vga_int.h         |    8 ++++----
 include/ui/console.h |   22 +++++++++++-----------
 ui/console.c         |   49 ++++++++++++++++++++++++++++++-------------------
 ui/curses.c          |    4 ++--
 ui/gtk.c             |    2 +-
 ui/sdl.c             |   18 +++++++++---------
 ui/spice-display.c   |    2 +-
 ui/vnc.c             |   12 ++++++------
 11 files changed, 67 insertions(+), 56 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 7a4d634..8a0f74f 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -720,7 +720,7 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
     /* we have to flush all pending changes so that the copy
        is generated at the appropriate moment in time */
     if (notify)
-	vga_hw_update();
+        graphic_hw_update(s->vga.con);
 
     (*s->cirrus_rop) (s, s->vga.vram_ptr +
 		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
diff --git a/hw/qxl.c b/hw/qxl.c
index b66b414..1ceee7e 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1074,7 +1074,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
     qemu_spice_create_host_primary(&d->ssd);
     d->mode = QXL_MODE_VGA;
     vga_dirty_log_start(&d->vga);
-    vga_hw_update();
+    graphic_hw_update(d->vga.con);
 }
 
 static void qxl_exit_vga_mode(PCIQXLDevice *d)
diff --git a/hw/vga.c b/hw/vga.c
index 59bfb22..533b60e 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2452,6 +2452,6 @@ static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
     if (cswitch) {
         vga_invalidate_display(s);
     }
-    vga_hw_update();
+    graphic_hw_update(s->con);
     ppm_save(filename, surface, errp);
 }
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 260f7d6..1b8f670 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -152,10 +152,10 @@ typedef struct VGACommonState {
     uint32_t cursor_offset;
     unsigned int (*rgb_to_pixel)(unsigned int r,
                                  unsigned int g, unsigned b);
-    vga_hw_update_ptr update;
-    vga_hw_invalidate_ptr invalidate;
-    vga_hw_screen_dump_ptr screen_dump;
-    vga_hw_text_update_ptr text_update;
+    graphic_hw_update_ptr update;
+    graphic_hw_invalidate_ptr invalidate;
+    graphic_hw_screen_dump_ptr screen_dump;
+    graphic_hw_text_update_ptr text_update;
     bool full_update_text;
     bool full_update_gfx;
     /* hardware mouse cursor support */
diff --git a/include/ui/console.h b/include/ui/console.h
index 3725dae..9c585c0 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -278,21 +278,21 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
     *dest = ch;
 }
 
-typedef void (*vga_hw_update_ptr)(void *);
-typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
+typedef void (*graphic_hw_update_ptr)(void *);
+typedef void (*graphic_hw_invalidate_ptr)(void *);
+typedef void (*graphic_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
                                        Error **errp);
-typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
+typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
 
-QemuConsole *graphic_console_init(vga_hw_update_ptr update,
-                                  vga_hw_invalidate_ptr invalidate,
-                                  vga_hw_screen_dump_ptr screen_dump,
-                                  vga_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
+                                  graphic_hw_invalidate_ptr invalidate,
+                                  graphic_hw_screen_dump_ptr screen_dump,
+                                  graphic_hw_text_update_ptr text_update,
                                   void *opaque);
 
-void vga_hw_update(void);
-void vga_hw_invalidate(void);
-void vga_hw_text_update(console_ch_t *chardata);
+void graphic_hw_update(QemuConsole *con);
+void graphic_hw_invalidate(QemuConsole *con);
+void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
 
 int is_graphic_console(void);
 int is_fixedsize_console(void);
diff --git a/ui/console.c b/ui/console.c
index 29f1805..7eddc82 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -118,10 +118,10 @@ struct QemuConsole {
     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;
+    graphic_hw_update_ptr hw_update;
+    graphic_hw_invalidate_ptr hw_invalidate;
+    graphic_hw_screen_dump_ptr hw_screen_dump;
+    graphic_hw_text_update_ptr hw_text_update;
     void *hw;
     int g_width, g_height;
 
@@ -165,16 +165,24 @@ static int nb_consoles = 0;
 
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
 
-void vga_hw_update(void)
+void graphic_hw_update(QemuConsole *con)
 {
-    if (active_console && active_console->hw_update)
-        active_console->hw_update(active_console->hw);
+    if (!con) {
+        con = active_console;
+    }
+    if (con && con->hw_update) {
+        con->hw_update(con->hw);
+    }
 }
 
-void vga_hw_invalidate(void)
+void graphic_hw_invalidate(QemuConsole *con)
 {
-    if (active_console && active_console->hw_invalidate)
-        active_console->hw_invalidate(active_console->hw);
+    if (!con) {
+        con = active_console;
+    }
+    if (con && con->hw_invalidate) {
+        con->hw_invalidate(con->hw);
+    }
 }
 
 void qmp_screendump(const char *filename, Error **errp)
@@ -201,10 +209,13 @@ void qmp_screendump(const char *filename, Error **errp)
     }
 }
 
-void vga_hw_text_update(console_ch_t *chardata)
+void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
 {
-    if (active_console && active_console->hw_text_update)
-        active_console->hw_text_update(active_console->hw, chardata);
+    if (!con) {
+        con = active_console;
+    }
+    if (con && con->hw_text_update)
+        con->hw_text_update(con->hw, chardata);
 }
 
 static void vga_fill_rect(QemuConsole *con,
@@ -932,7 +943,7 @@ void console_select(unsigned int index)
             qemu_mod_timer(s->cursor_timer,
                    qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
         }
-        vga_hw_invalidate();
+        graphic_hw_invalidate(s);
     }
 }
 
@@ -1359,10 +1370,10 @@ DisplayState *init_displaystate(void)
     return display_state;
 }
 
-QemuConsole *graphic_console_init(vga_hw_update_ptr update,
-                                  vga_hw_invalidate_ptr invalidate,
-                                  vga_hw_screen_dump_ptr screen_dump,
-                                  vga_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
+                                  graphic_hw_invalidate_ptr invalidate,
+                                  graphic_hw_screen_dump_ptr screen_dump,
+                                  graphic_hw_text_update_ptr text_update,
                                   void *opaque)
 {
     int width = 640;
@@ -1407,7 +1418,7 @@ static void text_console_update_cursor(void *opaque)
     QemuConsole *s = opaque;
 
     s->cursor_visible_phase = !s->cursor_visible_phase;
-    vga_hw_invalidate();
+    graphic_hw_invalidate(s);
     qemu_mod_timer(s->cursor_timer,
                    qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
 }
diff --git a/ui/curses.c b/ui/curses.c
index ff82307..ed9e65c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -166,11 +166,11 @@ static void curses_refresh(DisplayChangeListener *dcl)
         clear();
         refresh();
         curses_calc_pad();
-        vga_hw_invalidate();
+        graphic_hw_invalidate(NULL);
         invalidate = 0;
     }
 
-    vga_hw_text_update(screen);
+    graphic_hw_text_update(NULL, screen);
 
     nextchr = ERR;
     while (1) {
diff --git a/ui/gtk.c b/ui/gtk.c
index 1a6bee6..ef2665a 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -327,7 +327,7 @@ static void gd_update(DisplayChangeListener *dcl,
 
 static void gd_refresh(DisplayChangeListener *dcl)
 {
-    vga_hw_update();
+    graphic_hw_update(NULL);
 }
 
 static void gd_switch(DisplayChangeListener *dcl,
diff --git a/ui/sdl.c b/ui/sdl.c
index 8da0534..ede31dc 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -492,8 +492,8 @@ static void toggle_full_screen(void)
             sdl_grab_end();
         }
     }
-    vga_hw_invalidate();
-    vga_hw_update();
+    graphic_hw_invalidate(NULL);
+    graphic_hw_update(NULL);
 }
 
 static void handle_keydown(SDL_Event *ev)
@@ -522,8 +522,8 @@ static void handle_keydown(SDL_Event *ev)
             if (scaling_active) {
                 scaling_active = 0;
                 sdl_switch(dcl, NULL);
-                vga_hw_invalidate();
-                vga_hw_update();
+                graphic_hw_invalidate(NULL);
+                graphic_hw_update(NULL);
             }
             gui_keysym = 1;
             break;
@@ -556,8 +556,8 @@ static void handle_keydown(SDL_Event *ev)
                     surface_width(surface);
 
                 sdl_scale(width, height);
-                vga_hw_invalidate();
-                vga_hw_update();
+                graphic_hw_invalidate(NULL);
+                graphic_hw_update(NULL);
                 gui_keysym = 1;
             }
         default:
@@ -770,7 +770,7 @@ static void sdl_refresh(DisplayChangeListener *dcl)
         sdl_update_caption();
     }
 
-    vga_hw_update();
+    graphic_hw_update(NULL);
     SDL_EnableUNICODE(!is_graphic_console());
 
     while (SDL_PollEvent(ev)) {
@@ -802,8 +802,8 @@ static void sdl_refresh(DisplayChangeListener *dcl)
             break;
         case SDL_VIDEORESIZE:
             sdl_scale(ev->resize.w, ev->resize.h);
-            vga_hw_invalidate();
-            vga_hw_update();
+            graphic_hw_invalidate(NULL);
+            graphic_hw_update(NULL);
             break;
         default:
             break;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index eaab19d..2c01674 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -414,7 +414,7 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
 {
     dprint(3, "%s:\n", __func__);
-    vga_hw_update();
+    graphic_hw_update(ssd->con);
 
     qemu_mutex_lock(&ssd->lock);
     if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) {
diff --git a/ui/vnc.c b/ui/vnc.c
index 5ddb696..bc787cc 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1956,8 +1956,8 @@ static void set_pixel_format(VncState *vs,
 
     set_pixel_conversion(vs);
 
-    vga_hw_invalidate();
-    vga_hw_update();
+    graphic_hw_invalidate(NULL);
+    graphic_hw_update(NULL);
 }
 
 static void pixel_format_message (VncState *vs) {
@@ -2653,7 +2653,7 @@ static void vnc_refresh(void *opaque)
     VncState *vs, *vn;
     int has_dirty, rects = 0;
 
-    vga_hw_update();
+    graphic_hw_update(NULL);
 
     if (vnc_trylock_display(vd)) {
         vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
@@ -2692,7 +2692,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);
-        vga_hw_update();
+        graphic_hw_update(NULL);
         vnc_refresh(vd);
     }
 }
@@ -2775,7 +2775,7 @@ void vnc_init_state(VncState *vs)
 
     QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
 
-    vga_hw_update();
+    graphic_hw_update(NULL);
 
     vnc_write(vs, "RFB 003.008\n", 12);
     vnc_flush(vs);
@@ -2800,7 +2800,7 @@ static void vnc_listen_read(void *opaque, bool websocket)
     int csock;
 
     /* Catch-up */
-    vga_hw_update();
+    graphic_hw_update(NULL);
 #ifdef CONFIG_VNC_WS
     if (websocket) {
         csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 13/24] console: give each QemuConsole its own DisplaySurface
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 12/24] console: rename vga_hw_*, add QemuConsole param Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28   ` Gerd Hoffmann
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

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

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |    1 -
 ui/console.c         |   96 ++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 69 insertions(+), 28 deletions(-)

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

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

* [Qemu-devel] [PATCH 14/24] console: simplify screendump
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
@ 2013-04-04  7:28   ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
                     ` (22 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Guan Xuetao, Igor Mitsyanko,
	Evgeny Voevodin, Stefano Stabellini, open list:X86,
	Gerd Hoffmann, Maksim Kozlov, Dmitry Solodkiy

Screendumps are alot simpler as we can update non-active
QemuConsoles now.  So we only need to update the QemuConsole
we want write out, then dump the DisplaySurface content into
a ppm file.  Done.

No console switching needed.  No special support code in the
gfx card emulation needed.  Zap it all.  Also move ppm_save
out of the vga code and next to the qmp_screendump function.

For now screen dumping is limited to console #0 (like it used
to be), even though it is dead simple to extend it to other
consoles.  I wanna finish the console cleanup before setting
new qapi interfaces into stone.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
---
 hw/arm/musicpal.c    |    2 +-
 hw/blizzard.c        |   14 +-----
 hw/cirrus_vga.c      |    4 +-
 hw/exynos4210_fimd.c |    2 +-
 hw/g364fb.c          |   73 +---------------------------
 hw/jazz_led.c        |    1 -
 hw/milkymist-vgafb.c |    2 +-
 hw/omap_lcdc.c       |   86 +--------------------------------
 hw/pl110.c           |    2 +-
 hw/pxa2xx_lcd.c      |    2 +-
 hw/qxl.c             |   22 +--------
 hw/sm501.c           |    2 +-
 hw/ssd0303.c         |    2 +-
 hw/ssd0323.c         |    2 +-
 hw/tc6393xb.c        |    1 -
 hw/tcx.c             |  129 +-------------------------------------------------
 hw/unicore32/puv3.c  |    2 +-
 hw/vga-isa-mm.c      |    2 +-
 hw/vga-isa.c         |    2 +-
 hw/vga-pci.c         |    2 +-
 hw/vga.c             |   66 --------------------------
 hw/vga_int.h         |    2 -
 hw/vmware_vga.c      |   26 ----------
 hw/xenfb.c           |    1 -
 include/ui/console.h |    3 --
 ui/console.c         |   72 ++++++++++++++++++++--------
 26 files changed, 73 insertions(+), 451 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index ea8473d..0258373 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -612,7 +612,7 @@ static int musicpal_lcd_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
 
     s->con = graphic_console_init(lcd_refresh, lcd_invalidate,
-                                  NULL, NULL, s);
+                                  NULL, s);
     qemu_console_resize(s->con, 128*3, 64*3);
 
     qdev_init_gpio_in(&dev->qdev, musicpal_lcd_gpio_brigthness_in, 3);
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 020d3de..891bff8 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -933,18 +933,6 @@ static void blizzard_update_display(void *opaque)
     s->my[1] = 0;
 }
 
-static void blizzard_screen_dump(void *opaque, const char *filename,
-                                 bool cswitch, Error **errp)
-{
-    BlizzardState *s = (BlizzardState *) opaque;
-    DisplaySurface *surface = qemu_console_surface(s->con);
-
-    blizzard_update_display(opaque);
-    if (s && surface_data(surface)) {
-        ppm_save(filename, surface, errp);
-    }
-}
-
 #define DEPTH 8
 #include "hw/blizzard_template.h"
 #define DEPTH 15
@@ -965,7 +953,7 @@ void *s1d13745_init(qemu_irq gpio_int)
 
     s->con = graphic_console_init(blizzard_update_display,
                                   blizzard_invalidate_display,
-                                  blizzard_screen_dump, NULL, s);
+                                  NULL, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 8a0f74f..03b3245 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2911,7 +2911,7 @@ static int vga_initfn(ISADevice *dev)
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
                        isa_address_space(dev), isa_address_space_io(dev));
     s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->screen_dump, s->text_update,
+                                  s->text_update,
                                   s);
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
     /* XXX ISA-LFB support */
@@ -2960,7 +2960,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
      cirrus_init_common(s, device_id, 1, pci_address_space(dev),
                         pci_address_space_io(dev));
      s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                       s->vga.screen_dump, s->vga.text_update,
+                                       s->vga.text_update,
                                        &s->vga);
 
      /* setup PCI */
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 333456a..8178917 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1902,7 +1902,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
             "exynos4210.fimd", FIMD_REGS_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
     s->console = graphic_console_init(exynos4210_fimd_update,
-                                  exynos4210_fimd_invalidate, NULL, NULL, s);
+                                      exynos4210_fimd_invalidate, NULL, s);
 
     return 0;
 }
diff --git a/hw/g364fb.c b/hw/g364fb.c
index f7014e9..b70fe8a 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -294,77 +294,6 @@ static void g364fb_reset(G364State *s)
     g364fb_invalidate_display(s);
 }
 
-static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,
-                               Error **errp)
-{
-    G364State *s = opaque;
-    int ret, y, x;
-    uint8_t index;
-    uint8_t *data_buffer;
-    FILE *f;
-
-    qemu_flush_coalesced_mmio_buffer();
-
-    if (s->depth != 8) {
-        error_setg(errp, "g364: unknown guest depth %d", s->depth);
-        return;
-    }
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-
-    if (s->ctla & CTLA_FORCE_BLANK) {
-        /* blank screen */
-        ret = fprintf(f, "P4\n%d %d\n", s->width, s->height);
-        if (ret < 0) {
-            goto write_err;
-        }
-        for (y = 0; y < s->height; y++)
-            for (x = 0; x < s->width; x++) {
-                ret = fputc(0, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-            }
-    } else {
-        data_buffer = s->vram + s->top_of_screen;
-        ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
-        if (ret < 0) {
-            goto write_err;
-        }
-        for (y = 0; y < s->height; y++)
-            for (x = 0; x < s->width; x++, data_buffer++) {
-                index = *data_buffer;
-                ret = fputc(s->color_palette[index][0], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->color_palette[index][1], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->color_palette[index][2], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-        }
-    }
-
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
 /* called for accesses to io ports */
 static uint64_t g364fb_ctrl_read(void *opaque,
                                  hwaddr addr,
@@ -552,7 +481,7 @@ static void g364fb_init(DeviceState *dev, G364State *s)
 
     s->con = graphic_console_init(g364fb_update_display,
                                   g364fb_invalidate_display,
-                                  g364fb_screen_dump, NULL, s);
+                                  NULL, s);
 
     memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
     memory_region_init_ram_ptr(&s->mem_vram, "vram",
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 05528c7..c027f76 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -263,7 +263,6 @@ static int jazz_led_init(SysBusDevice *dev)
 
     s->con = graphic_console_init(jazz_led_update_display,
                                   jazz_led_invalidate_display,
-                                  NULL,
                                   jazz_led_text_update, s);
 
     return 0;
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 98762ec..80486e8 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -280,7 +280,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
 
     s->con = graphic_console_init(vgafb_update_display,
                                   vgafb_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
 
     return 0;
 }
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 4f5b094..1cb49d5 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -227,90 +227,6 @@ static void omap_update_display(void *opaque)
     omap_lcd->invalidate = 0;
 }
 
-static void omap_ppm_save(const char *filename, uint8_t *data,
-                    int w, int h, int linesize, Error **errp)
-{
-    FILE *f;
-    uint8_t *d, *d1;
-    unsigned int v;
-    int ret, y, x, bpp;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
-    if (ret < 0) {
-        goto write_err;
-    }
-    d1 = data;
-    bpp = linesize / w;
-    for (y = 0; y < h; y ++) {
-        d = d1;
-        for (x = 0; x < w; x ++) {
-            v = *(uint32_t *) d;
-            switch (bpp) {
-            case 2:
-                ret = fputc((v >> 8) & 0xf8, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v >> 3) & 0xfc, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v << 3) & 0xf8, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                break;
-            case 3:
-            case 4:
-            default:
-                ret = fputc((v >> 16) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v >> 8) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                break;
-            }
-            d += bpp;
-        }
-        d1 += linesize;
-    }
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
-static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
-                             Error **errp)
-{
-    struct omap_lcd_panel_s *omap_lcd = opaque;
-    DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
-
-    omap_update_display(opaque);
-    if (omap_lcd && surface_data(surface))
-        omap_ppm_save(filename, surface_data(surface),
-                    omap_lcd->width, omap_lcd->height,
-                    surface_stride(surface), errp);
-}
-
 static void omap_invalidate_display(void *opaque) {
     struct omap_lcd_panel_s *omap_lcd = opaque;
     omap_lcd->invalidate = 1;
@@ -487,7 +403,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
 
     s->con = graphic_console_init(omap_update_display,
                                   omap_invalidate_display,
-                                  omap_screen_dump, NULL, s);
+                                  NULL, s);
 
     return s;
 }
diff --git a/hw/pl110.c b/hw/pl110.c
index fbef675..6f24957 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -454,7 +454,7 @@ static int pl110_init(SysBusDevice *dev)
     qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
     s->con = graphic_console_init(pl110_update_display,
                                   pl110_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     return 0;
 }
 
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index f2b0c93..602e3dc 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -1010,7 +1010,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
 
     s->con = graphic_console_init(pxa2xx_update_display,
                                   pxa2xx_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 1ceee7e..0f09bae 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1772,26 +1772,6 @@ static void qxl_hw_invalidate(void *opaque)
     vga->invalidate(vga);
 }
 
-static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch,
-                               Error **errp)
-{
-    PCIQXLDevice *qxl = opaque;
-    VGACommonState *vga = &qxl->vga;
-
-    switch (qxl->mode) {
-    case QXL_MODE_COMPAT:
-    case QXL_MODE_NATIVE:
-        qxl_render_update(qxl);
-        ppm_save(filename, qxl->ssd.ds, errp);
-        break;
-    case QXL_MODE_VGA:
-        vga->screen_dump(vga, filename, cswitch, errp);
-        break;
-    default:
-        break;
-    }
-}
-
 static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
 {
     PCIQXLDevice *qxl = opaque;
@@ -2075,7 +2055,7 @@ static int qxl_init_primary(PCIDevice *dev)
     portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
 
     vga->con = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
-                                    qxl_hw_screen_dump, qxl_hw_text_update,
+                                    qxl_hw_text_update,
                                     qxl);
     qxl->ssd.con = vga->con,
     qemu_spice_display_init_common(&qxl->ssd);
diff --git a/hw/sm501.c b/hw/sm501.c
index 93a06c9..1f428cd 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1446,5 +1446,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
 
     /* create qemu graphic console */
     s->con = graphic_console_init(sm501_update_display, NULL,
-                                  NULL, NULL, s);
+                                  NULL, s);
 }
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 68d1f24..02feaff 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -290,7 +290,7 @@ static int ssd0303_init(I2CSlave *i2c)
 
     s->con = graphic_console_init(ssd0303_update_display,
                                   ssd0303_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
     return 0;
 }
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 5cf2f70..301cb20 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -339,7 +339,7 @@ static int ssd0323_init(SSISlave *dev)
     s->row_end = 79;
     s->con = graphic_console_init(ssd0323_update_display,
                                   ssd0323_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 
     qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 79c971b..30b624e 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -585,7 +585,6 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
     s->scr_height = 640;
     s->con = graphic_console_init(tc6393xb_update_display,
             NULL, /* invalidate */
-            NULL, /* screen_dump */
             NULL, /* text_update */
             s);
 
diff --git a/hw/tcx.c b/hw/tcx.c
index c44068e..ba3857a 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -56,11 +56,6 @@ typedef struct TCXState {
     uint8_t dac_index, dac_state;
 } TCXState;
 
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp);
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp);
-
 static void tcx_set_dirty(TCXState *s)
 {
     memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
@@ -569,7 +564,7 @@ static int tcx_init1(SysBusDevice *dev)
 
         s->con = graphic_console_init(tcx24_update_display,
                                       tcx24_invalidate_display,
-                                      tcx24_screen_dump, NULL, s);
+                                      NULL, s);
     } else {
         /* THC 8 bit (dummy) */
         memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
@@ -578,133 +573,13 @@ static int tcx_init1(SysBusDevice *dev)
 
         s->con = graphic_console_init(tcx_update_display,
                                       tcx_invalidate_display,
-                                      tcx_screen_dump, NULL, s);
+                                      NULL, s);
     }
 
     qemu_console_resize(s->con, s->width, s->height);
     return 0;
 }
 
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp)
-{
-    TCXState *s = opaque;
-    FILE *f;
-    uint8_t *d, *d1, v;
-    int ret, y, x;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
-    if (ret < 0) {
-        goto write_err;
-    }
-    d1 = s->vram;
-    for(y = 0; y < s->height; y++) {
-        d = d1;
-        for(x = 0; x < s->width; x++) {
-            v = *d;
-            ret = fputc(s->r[v], f);
-            if (ret == EOF) {
-                goto write_err;
-            }
-            ret = fputc(s->g[v], f);
-            if (ret == EOF) {
-                goto write_err;
-            }
-            ret = fputc(s->b[v], f);
-            if (ret == EOF) {
-                goto write_err;
-            }
-            d++;
-        }
-        d1 += MAXX;
-    }
-
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
-                              Error **errp)
-{
-    TCXState *s = opaque;
-    FILE *f;
-    uint8_t *d, *d1, v;
-    uint32_t *s24, *cptr, dval;
-    int ret, y, x;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
-    if (ret < 0) {
-        goto write_err;
-    }
-    d1 = s->vram;
-    s24 = s->vram24;
-    cptr = s->cplane;
-    for(y = 0; y < s->height; y++) {
-        d = d1;
-        for(x = 0; x < s->width; x++, d++, s24++) {
-            if ((*cptr++ & 0xff000000) == 0x03000000) { // 24-bit direct
-                dval = *s24 & 0x00ffffff;
-                ret = fputc((dval >> 16) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((dval >> 8) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(dval & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-            } else {
-                v = *d;
-                ret = fputc(s->r[v], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->g[v], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->b[v], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-            }
-        }
-        d1 += MAXX;
-    }
-
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
 static Property tcx_properties[] = {
     DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
     DEFINE_PROP_UINT16("width",    TCXState, width,     -1),
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 78ab13f..d110363 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -92,7 +92,7 @@ static void puv3_load_kernel(const char *kernel_filename)
     }
 
     /* cheat curses that we have a graphic console, only under ocd console */
-    graphic_console_init(NULL, NULL, NULL, NULL, NULL);
+    graphic_console_init(NULL, NULL, NULL, NULL);
 }
 
 static void puv3_init(QEMUMachineInitArgs *args)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 02356d4..5fb04fb 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -136,7 +136,7 @@ int isa_vga_mm_init(hwaddr vram_base,
     vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
 
     s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                      s->vga.screen_dump, s->vga.text_update,
+                                      s->vga.text_update,
                                       s);
 
     vga_init_vbe(&s->vga, address_space);
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 9e29321..0a1aded 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -63,7 +63,7 @@ static int vga_initfn(ISADevice *dev)
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
     s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->screen_dump, s->text_update, s);
+                                  s->text_update, s);
 
     vga_init_vbe(s, isa_address_space(dev));
     /* ROM BIOS */
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 05fa9bc..a982f2a 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -151,7 +151,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
     vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
 
     s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->screen_dump, s->text_update, s);
+                                  s->text_update, s);
 
     /* XXX: VGA_RAM_SIZE must be a power of two */
     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
diff --git a/hw/vga.c b/hw/vga.c
index 533b60e..a875faa 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -166,9 +166,6 @@ static uint32_t expand4[256];
 static uint16_t expand2[256];
 static uint8_t expand4to8[16];
 
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp);
-
 static void vga_update_memory_access(VGACommonState *s)
 {
     MemoryRegion *region, *old_region = s->chain4_alias;
@@ -2298,7 +2295,6 @@ void vga_common_init(VGACommonState *s)
     s->get_resolution = vga_get_resolution;
     s->update = vga_update_display;
     s->invalidate = vga_invalidate_display;
-    s->screen_dump = vga_screen_dump;
     s->text_update = vga_update_text;
     switch (vga_retrace_method) {
     case VGA_RETRACE_DUMB:
@@ -2393,65 +2389,3 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
                                 &s->vram_vbe);
     s->vbe_mapped = 1;
 }
-/********************************************************/
-/* vga screen dump */
-
-void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
-{
-    int width = pixman_image_get_width(ds->image);
-    int height = pixman_image_get_height(ds->image);
-    FILE *f;
-    int y;
-    int ret;
-    pixman_image_t *linebuf;
-
-    trace_ppm_save(filename, ds);
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
-    if (ret < 0) {
-        linebuf = NULL;
-        goto write_err;
-    }
-    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
-    for (y = 0; y < height; y++) {
-        qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
-        clearerr(f);
-        ret = fwrite(pixman_image_get_data(linebuf), 1,
-                     pixman_image_get_stride(linebuf), f);
-        (void)ret;
-        if (ferror(f)) {
-            goto write_err;
-        }
-    }
-
-out:
-    qemu_pixman_image_unref(linebuf);
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
-/* save the vga display in a PPM image even if no display is
-   available */
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp)
-{
-    VGACommonState *s = opaque;
-    DisplaySurface *surface = qemu_console_surface(s->con);
-
-    if (cswitch) {
-        vga_invalidate_display(s);
-    }
-    graphic_hw_update(s->con);
-    ppm_save(filename, surface, errp);
-}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 1b8f670..e4bb4a0 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -154,7 +154,6 @@ typedef struct VGACommonState {
                                  unsigned int g, unsigned b);
     graphic_hw_update_ptr update;
     graphic_hw_invalidate_ptr invalidate;
-    graphic_hw_screen_dump_ptr screen_dump;
     graphic_hw_text_update_ptr text_update;
     bool full_update_text;
     bool full_update_gfx;
@@ -198,7 +197,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
 uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr);
 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val);
 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
-void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp);
 
 int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
 
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 0d9a584..1ecee8f 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1119,31 +1119,6 @@ static void vmsvga_invalidate_display(void *opaque)
     s->invalidated = 1;
 }
 
-/* save the vga display in a PPM image even if no display is
-   available */
-static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch,
-                               Error **errp)
-{
-    struct vmsvga_state_s *s = opaque;
-    DisplaySurface *surface = qemu_console_surface(s->vga.con);
-
-    if (!s->enable) {
-        s->vga.screen_dump(&s->vga, filename, cswitch, errp);
-        return;
-    }
-
-    if (surface_bits_per_pixel(surface) == 32) {
-        DisplaySurface *ds = qemu_create_displaysurface_from(
-                                 surface_width(surface),
-                                 surface_height(surface),
-                                 32,
-                                 surface_stride(surface),
-                                 s->vga.vram_ptr, false);
-        ppm_save(filename, ds, errp);
-        g_free(ds);
-    }
-}
-
 static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
 {
     struct vmsvga_state_s *s = opaque;
@@ -1212,7 +1187,6 @@ static void vmsvga_init(struct vmsvga_state_s *s,
 
     s->vga.con = graphic_console_init(vmsvga_update_display,
                                       vmsvga_invalidate_display,
-                                      vmsvga_screen_dump,
                                       vmsvga_text_update, s);
 
     s->fifo_size = SVGA_FIFO_SIZE;
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 7c46a2f..0db2f84 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -1007,7 +1007,6 @@ wait_more:
     fb->c.con = graphic_console_init(xenfb_update,
                                      xenfb_invalidate,
                                      NULL,
-                                     NULL,
                                      fb);
     fb->have_console = 1;
 
diff --git a/include/ui/console.h b/include/ui/console.h
index 0dd66fd..d6e3e92 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -279,13 +279,10 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 
 typedef void (*graphic_hw_update_ptr)(void *);
 typedef void (*graphic_hw_invalidate_ptr)(void *);
-typedef void (*graphic_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
-                                       Error **errp);
 typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
 
 QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
                                   graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_screen_dump_ptr screen_dump,
                                   graphic_hw_text_update_ptr text_update,
                                   void *opaque);
 
diff --git a/ui/console.c b/ui/console.c
index 331d942..8893e8b 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -121,7 +121,6 @@ struct QemuConsole {
     /* Graphic console state.  */
     graphic_hw_update_ptr hw_update;
     graphic_hw_invalidate_ptr hw_invalidate;
-    graphic_hw_screen_dump_ptr hw_screen_dump;
     graphic_hw_text_update_ptr hw_text_update;
     void *hw;
     int g_width, g_height;
@@ -188,28 +187,65 @@ void graphic_hw_invalidate(QemuConsole *con)
     }
 }
 
-void qmp_screendump(const char *filename, Error **errp)
+static void ppm_save(const char *filename, struct DisplaySurface *ds,
+                     Error **errp)
 {
-    QemuConsole *previous_active_console;
-    bool cswitch;
-
-    previous_active_console = active_console;
-    cswitch = previous_active_console && previous_active_console->index != 0;
+    int width = pixman_image_get_width(ds->image);
+    int height = pixman_image_get_height(ds->image);
+    FILE *f;
+    int y;
+    int ret;
+    pixman_image_t *linebuf;
 
-    /* There is currently no way of specifying which screen we want to dump,
-       so always dump the first one.  */
-    if (cswitch) {
-        console_select(0);
+    trace_ppm_save(filename, ds);
+    f = fopen(filename, "wb");
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
+        return;
     }
-    if (consoles[0] && consoles[0]->hw_screen_dump) {
-        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
-    } else {
-        error_setg(errp, "device doesn't support screendump");
+    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
+    if (ret < 0) {
+        linebuf = NULL;
+        goto write_err;
+    }
+    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
+    for (y = 0; y < height; y++) {
+        qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
+        clearerr(f);
+        ret = fwrite(pixman_image_get_data(linebuf), 1,
+                     pixman_image_get_stride(linebuf), f);
+        (void)ret;
+        if (ferror(f)) {
+            goto write_err;
+        }
     }
 
-    if (cswitch) {
-        console_select(previous_active_console->index);
+out:
+    qemu_pixman_image_unref(linebuf);
+    fclose(f);
+    return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
+}
+
+void qmp_screendump(const char *filename, Error **errp)
+{
+    QemuConsole *con = consoles[0];
+    DisplaySurface *surface;
+
+    if (con == NULL) {
+        error_setg(errp, "There is no QemuConsole I can screendump from.");
+        return;
     }
+
+    graphic_hw_update(con);
+    surface = qemu_console_surface(con);
+    ppm_save(filename, surface, errp);
 }
 
 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
@@ -1411,7 +1447,6 @@ DisplayState *init_displaystate(void)
 
 QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
                                   graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_screen_dump_ptr screen_dump,
                                   graphic_hw_text_update_ptr text_update,
                                   void *opaque)
 {
@@ -1425,7 +1460,6 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
     s = new_console(ds, GRAPHIC_CONSOLE);
     s->hw_update = update;
     s->hw_invalidate = invalidate;
-    s->hw_screen_dump = screen_dump;
     s->hw_text_update = text_update;
     s->hw = opaque;
 
-- 
1.7.9.7

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

* [PATCH 14/24] console: simplify screendump
@ 2013-04-04  7:28   ` Gerd Hoffmann
  0 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Guan Xuetao, Igor Mitsyanko,
	Evgeny Voevodin, Stefano Stabellini, open list:X86,
	Gerd Hoffmann, Maksim Kozlov, Dmitry Solodkiy

Screendumps are alot simpler as we can update non-active
QemuConsoles now.  So we only need to update the QemuConsole
we want write out, then dump the DisplaySurface content into
a ppm file.  Done.

No console switching needed.  No special support code in the
gfx card emulation needed.  Zap it all.  Also move ppm_save
out of the vga code and next to the qmp_screendump function.

For now screen dumping is limited to console #0 (like it used
to be), even though it is dead simple to extend it to other
consoles.  I wanna finish the console cleanup before setting
new qapi interfaces into stone.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
---
 hw/arm/musicpal.c    |    2 +-
 hw/blizzard.c        |   14 +-----
 hw/cirrus_vga.c      |    4 +-
 hw/exynos4210_fimd.c |    2 +-
 hw/g364fb.c          |   73 +---------------------------
 hw/jazz_led.c        |    1 -
 hw/milkymist-vgafb.c |    2 +-
 hw/omap_lcdc.c       |   86 +--------------------------------
 hw/pl110.c           |    2 +-
 hw/pxa2xx_lcd.c      |    2 +-
 hw/qxl.c             |   22 +--------
 hw/sm501.c           |    2 +-
 hw/ssd0303.c         |    2 +-
 hw/ssd0323.c         |    2 +-
 hw/tc6393xb.c        |    1 -
 hw/tcx.c             |  129 +-------------------------------------------------
 hw/unicore32/puv3.c  |    2 +-
 hw/vga-isa-mm.c      |    2 +-
 hw/vga-isa.c         |    2 +-
 hw/vga-pci.c         |    2 +-
 hw/vga.c             |   66 --------------------------
 hw/vga_int.h         |    2 -
 hw/vmware_vga.c      |   26 ----------
 hw/xenfb.c           |    1 -
 include/ui/console.h |    3 --
 ui/console.c         |   72 ++++++++++++++++++++--------
 26 files changed, 73 insertions(+), 451 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index ea8473d..0258373 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -612,7 +612,7 @@ static int musicpal_lcd_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
 
     s->con = graphic_console_init(lcd_refresh, lcd_invalidate,
-                                  NULL, NULL, s);
+                                  NULL, s);
     qemu_console_resize(s->con, 128*3, 64*3);
 
     qdev_init_gpio_in(&dev->qdev, musicpal_lcd_gpio_brigthness_in, 3);
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 020d3de..891bff8 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -933,18 +933,6 @@ static void blizzard_update_display(void *opaque)
     s->my[1] = 0;
 }
 
-static void blizzard_screen_dump(void *opaque, const char *filename,
-                                 bool cswitch, Error **errp)
-{
-    BlizzardState *s = (BlizzardState *) opaque;
-    DisplaySurface *surface = qemu_console_surface(s->con);
-
-    blizzard_update_display(opaque);
-    if (s && surface_data(surface)) {
-        ppm_save(filename, surface, errp);
-    }
-}
-
 #define DEPTH 8
 #include "hw/blizzard_template.h"
 #define DEPTH 15
@@ -965,7 +953,7 @@ void *s1d13745_init(qemu_irq gpio_int)
 
     s->con = graphic_console_init(blizzard_update_display,
                                   blizzard_invalidate_display,
-                                  blizzard_screen_dump, NULL, s);
+                                  NULL, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 8a0f74f..03b3245 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2911,7 +2911,7 @@ static int vga_initfn(ISADevice *dev)
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
                        isa_address_space(dev), isa_address_space_io(dev));
     s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->screen_dump, s->text_update,
+                                  s->text_update,
                                   s);
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
     /* XXX ISA-LFB support */
@@ -2960,7 +2960,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
      cirrus_init_common(s, device_id, 1, pci_address_space(dev),
                         pci_address_space_io(dev));
      s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                       s->vga.screen_dump, s->vga.text_update,
+                                       s->vga.text_update,
                                        &s->vga);
 
      /* setup PCI */
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 333456a..8178917 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1902,7 +1902,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
             "exynos4210.fimd", FIMD_REGS_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
     s->console = graphic_console_init(exynos4210_fimd_update,
-                                  exynos4210_fimd_invalidate, NULL, NULL, s);
+                                      exynos4210_fimd_invalidate, NULL, s);
 
     return 0;
 }
diff --git a/hw/g364fb.c b/hw/g364fb.c
index f7014e9..b70fe8a 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -294,77 +294,6 @@ static void g364fb_reset(G364State *s)
     g364fb_invalidate_display(s);
 }
 
-static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,
-                               Error **errp)
-{
-    G364State *s = opaque;
-    int ret, y, x;
-    uint8_t index;
-    uint8_t *data_buffer;
-    FILE *f;
-
-    qemu_flush_coalesced_mmio_buffer();
-
-    if (s->depth != 8) {
-        error_setg(errp, "g364: unknown guest depth %d", s->depth);
-        return;
-    }
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-
-    if (s->ctla & CTLA_FORCE_BLANK) {
-        /* blank screen */
-        ret = fprintf(f, "P4\n%d %d\n", s->width, s->height);
-        if (ret < 0) {
-            goto write_err;
-        }
-        for (y = 0; y < s->height; y++)
-            for (x = 0; x < s->width; x++) {
-                ret = fputc(0, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-            }
-    } else {
-        data_buffer = s->vram + s->top_of_screen;
-        ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
-        if (ret < 0) {
-            goto write_err;
-        }
-        for (y = 0; y < s->height; y++)
-            for (x = 0; x < s->width; x++, data_buffer++) {
-                index = *data_buffer;
-                ret = fputc(s->color_palette[index][0], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->color_palette[index][1], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->color_palette[index][2], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-        }
-    }
-
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
 /* called for accesses to io ports */
 static uint64_t g364fb_ctrl_read(void *opaque,
                                  hwaddr addr,
@@ -552,7 +481,7 @@ static void g364fb_init(DeviceState *dev, G364State *s)
 
     s->con = graphic_console_init(g364fb_update_display,
                                   g364fb_invalidate_display,
-                                  g364fb_screen_dump, NULL, s);
+                                  NULL, s);
 
     memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
     memory_region_init_ram_ptr(&s->mem_vram, "vram",
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 05528c7..c027f76 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -263,7 +263,6 @@ static int jazz_led_init(SysBusDevice *dev)
 
     s->con = graphic_console_init(jazz_led_update_display,
                                   jazz_led_invalidate_display,
-                                  NULL,
                                   jazz_led_text_update, s);
 
     return 0;
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 98762ec..80486e8 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -280,7 +280,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
 
     s->con = graphic_console_init(vgafb_update_display,
                                   vgafb_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
 
     return 0;
 }
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 4f5b094..1cb49d5 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -227,90 +227,6 @@ static void omap_update_display(void *opaque)
     omap_lcd->invalidate = 0;
 }
 
-static void omap_ppm_save(const char *filename, uint8_t *data,
-                    int w, int h, int linesize, Error **errp)
-{
-    FILE *f;
-    uint8_t *d, *d1;
-    unsigned int v;
-    int ret, y, x, bpp;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
-    if (ret < 0) {
-        goto write_err;
-    }
-    d1 = data;
-    bpp = linesize / w;
-    for (y = 0; y < h; y ++) {
-        d = d1;
-        for (x = 0; x < w; x ++) {
-            v = *(uint32_t *) d;
-            switch (bpp) {
-            case 2:
-                ret = fputc((v >> 8) & 0xf8, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v >> 3) & 0xfc, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v << 3) & 0xf8, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                break;
-            case 3:
-            case 4:
-            default:
-                ret = fputc((v >> 16) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v >> 8) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((v) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                break;
-            }
-            d += bpp;
-        }
-        d1 += linesize;
-    }
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
-static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
-                             Error **errp)
-{
-    struct omap_lcd_panel_s *omap_lcd = opaque;
-    DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
-
-    omap_update_display(opaque);
-    if (omap_lcd && surface_data(surface))
-        omap_ppm_save(filename, surface_data(surface),
-                    omap_lcd->width, omap_lcd->height,
-                    surface_stride(surface), errp);
-}
-
 static void omap_invalidate_display(void *opaque) {
     struct omap_lcd_panel_s *omap_lcd = opaque;
     omap_lcd->invalidate = 1;
@@ -487,7 +403,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
 
     s->con = graphic_console_init(omap_update_display,
                                   omap_invalidate_display,
-                                  omap_screen_dump, NULL, s);
+                                  NULL, s);
 
     return s;
 }
diff --git a/hw/pl110.c b/hw/pl110.c
index fbef675..6f24957 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -454,7 +454,7 @@ static int pl110_init(SysBusDevice *dev)
     qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
     s->con = graphic_console_init(pl110_update_display,
                                   pl110_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     return 0;
 }
 
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index f2b0c93..602e3dc 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -1010,7 +1010,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
 
     s->con = graphic_console_init(pxa2xx_update_display,
                                   pxa2xx_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 1ceee7e..0f09bae 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1772,26 +1772,6 @@ static void qxl_hw_invalidate(void *opaque)
     vga->invalidate(vga);
 }
 
-static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch,
-                               Error **errp)
-{
-    PCIQXLDevice *qxl = opaque;
-    VGACommonState *vga = &qxl->vga;
-
-    switch (qxl->mode) {
-    case QXL_MODE_COMPAT:
-    case QXL_MODE_NATIVE:
-        qxl_render_update(qxl);
-        ppm_save(filename, qxl->ssd.ds, errp);
-        break;
-    case QXL_MODE_VGA:
-        vga->screen_dump(vga, filename, cswitch, errp);
-        break;
-    default:
-        break;
-    }
-}
-
 static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
 {
     PCIQXLDevice *qxl = opaque;
@@ -2075,7 +2055,7 @@ static int qxl_init_primary(PCIDevice *dev)
     portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
 
     vga->con = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
-                                    qxl_hw_screen_dump, qxl_hw_text_update,
+                                    qxl_hw_text_update,
                                     qxl);
     qxl->ssd.con = vga->con,
     qemu_spice_display_init_common(&qxl->ssd);
diff --git a/hw/sm501.c b/hw/sm501.c
index 93a06c9..1f428cd 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1446,5 +1446,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
 
     /* create qemu graphic console */
     s->con = graphic_console_init(sm501_update_display, NULL,
-                                  NULL, NULL, s);
+                                  NULL, s);
 }
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 68d1f24..02feaff 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -290,7 +290,7 @@ static int ssd0303_init(I2CSlave *i2c)
 
     s->con = graphic_console_init(ssd0303_update_display,
                                   ssd0303_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
     return 0;
 }
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 5cf2f70..301cb20 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -339,7 +339,7 @@ static int ssd0323_init(SSISlave *dev)
     s->row_end = 79;
     s->con = graphic_console_init(ssd0323_update_display,
                                   ssd0323_invalidate_display,
-                                  NULL, NULL, s);
+                                  NULL, s);
     qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 
     qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 79c971b..30b624e 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -585,7 +585,6 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
     s->scr_height = 640;
     s->con = graphic_console_init(tc6393xb_update_display,
             NULL, /* invalidate */
-            NULL, /* screen_dump */
             NULL, /* text_update */
             s);
 
diff --git a/hw/tcx.c b/hw/tcx.c
index c44068e..ba3857a 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -56,11 +56,6 @@ typedef struct TCXState {
     uint8_t dac_index, dac_state;
 } TCXState;
 
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp);
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp);
-
 static void tcx_set_dirty(TCXState *s)
 {
     memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
@@ -569,7 +564,7 @@ static int tcx_init1(SysBusDevice *dev)
 
         s->con = graphic_console_init(tcx24_update_display,
                                       tcx24_invalidate_display,
-                                      tcx24_screen_dump, NULL, s);
+                                      NULL, s);
     } else {
         /* THC 8 bit (dummy) */
         memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
@@ -578,133 +573,13 @@ static int tcx_init1(SysBusDevice *dev)
 
         s->con = graphic_console_init(tcx_update_display,
                                       tcx_invalidate_display,
-                                      tcx_screen_dump, NULL, s);
+                                      NULL, s);
     }
 
     qemu_console_resize(s->con, s->width, s->height);
     return 0;
 }
 
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp)
-{
-    TCXState *s = opaque;
-    FILE *f;
-    uint8_t *d, *d1, v;
-    int ret, y, x;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
-    if (ret < 0) {
-        goto write_err;
-    }
-    d1 = s->vram;
-    for(y = 0; y < s->height; y++) {
-        d = d1;
-        for(x = 0; x < s->width; x++) {
-            v = *d;
-            ret = fputc(s->r[v], f);
-            if (ret == EOF) {
-                goto write_err;
-            }
-            ret = fputc(s->g[v], f);
-            if (ret == EOF) {
-                goto write_err;
-            }
-            ret = fputc(s->b[v], f);
-            if (ret == EOF) {
-                goto write_err;
-            }
-            d++;
-        }
-        d1 += MAXX;
-    }
-
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
-                              Error **errp)
-{
-    TCXState *s = opaque;
-    FILE *f;
-    uint8_t *d, *d1, v;
-    uint32_t *s24, *cptr, dval;
-    int ret, y, x;
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
-    if (ret < 0) {
-        goto write_err;
-    }
-    d1 = s->vram;
-    s24 = s->vram24;
-    cptr = s->cplane;
-    for(y = 0; y < s->height; y++) {
-        d = d1;
-        for(x = 0; x < s->width; x++, d++, s24++) {
-            if ((*cptr++ & 0xff000000) == 0x03000000) { // 24-bit direct
-                dval = *s24 & 0x00ffffff;
-                ret = fputc((dval >> 16) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc((dval >> 8) & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(dval & 0xff, f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-            } else {
-                v = *d;
-                ret = fputc(s->r[v], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->g[v], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-                ret = fputc(s->b[v], f);
-                if (ret == EOF) {
-                    goto write_err;
-                }
-            }
-        }
-        d1 += MAXX;
-    }
-
-out:
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
 static Property tcx_properties[] = {
     DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
     DEFINE_PROP_UINT16("width",    TCXState, width,     -1),
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 78ab13f..d110363 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -92,7 +92,7 @@ static void puv3_load_kernel(const char *kernel_filename)
     }
 
     /* cheat curses that we have a graphic console, only under ocd console */
-    graphic_console_init(NULL, NULL, NULL, NULL, NULL);
+    graphic_console_init(NULL, NULL, NULL, NULL);
 }
 
 static void puv3_init(QEMUMachineInitArgs *args)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 02356d4..5fb04fb 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -136,7 +136,7 @@ int isa_vga_mm_init(hwaddr vram_base,
     vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
 
     s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                      s->vga.screen_dump, s->vga.text_update,
+                                      s->vga.text_update,
                                       s);
 
     vga_init_vbe(&s->vga, address_space);
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 9e29321..0a1aded 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -63,7 +63,7 @@ static int vga_initfn(ISADevice *dev)
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
     s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->screen_dump, s->text_update, s);
+                                  s->text_update, s);
 
     vga_init_vbe(s, isa_address_space(dev));
     /* ROM BIOS */
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 05fa9bc..a982f2a 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -151,7 +151,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
     vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
 
     s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->screen_dump, s->text_update, s);
+                                  s->text_update, s);
 
     /* XXX: VGA_RAM_SIZE must be a power of two */
     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
diff --git a/hw/vga.c b/hw/vga.c
index 533b60e..a875faa 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -166,9 +166,6 @@ static uint32_t expand4[256];
 static uint16_t expand2[256];
 static uint8_t expand4to8[16];
 
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp);
-
 static void vga_update_memory_access(VGACommonState *s)
 {
     MemoryRegion *region, *old_region = s->chain4_alias;
@@ -2298,7 +2295,6 @@ void vga_common_init(VGACommonState *s)
     s->get_resolution = vga_get_resolution;
     s->update = vga_update_display;
     s->invalidate = vga_invalidate_display;
-    s->screen_dump = vga_screen_dump;
     s->text_update = vga_update_text;
     switch (vga_retrace_method) {
     case VGA_RETRACE_DUMB:
@@ -2393,65 +2389,3 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
                                 &s->vram_vbe);
     s->vbe_mapped = 1;
 }
-/********************************************************/
-/* vga screen dump */
-
-void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
-{
-    int width = pixman_image_get_width(ds->image);
-    int height = pixman_image_get_height(ds->image);
-    FILE *f;
-    int y;
-    int ret;
-    pixman_image_t *linebuf;
-
-    trace_ppm_save(filename, ds);
-    f = fopen(filename, "wb");
-    if (!f) {
-        error_setg(errp, "failed to open file '%s': %s", filename,
-                   strerror(errno));
-        return;
-    }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
-    if (ret < 0) {
-        linebuf = NULL;
-        goto write_err;
-    }
-    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
-    for (y = 0; y < height; y++) {
-        qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
-        clearerr(f);
-        ret = fwrite(pixman_image_get_data(linebuf), 1,
-                     pixman_image_get_stride(linebuf), f);
-        (void)ret;
-        if (ferror(f)) {
-            goto write_err;
-        }
-    }
-
-out:
-    qemu_pixman_image_unref(linebuf);
-    fclose(f);
-    return;
-
-write_err:
-    error_setg(errp, "failed to write to file '%s': %s", filename,
-               strerror(errno));
-    unlink(filename);
-    goto out;
-}
-
-/* save the vga display in a PPM image even if no display is
-   available */
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
-                            Error **errp)
-{
-    VGACommonState *s = opaque;
-    DisplaySurface *surface = qemu_console_surface(s->con);
-
-    if (cswitch) {
-        vga_invalidate_display(s);
-    }
-    graphic_hw_update(s->con);
-    ppm_save(filename, surface, errp);
-}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 1b8f670..e4bb4a0 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -154,7 +154,6 @@ typedef struct VGACommonState {
                                  unsigned int g, unsigned b);
     graphic_hw_update_ptr update;
     graphic_hw_invalidate_ptr invalidate;
-    graphic_hw_screen_dump_ptr screen_dump;
     graphic_hw_text_update_ptr text_update;
     bool full_update_text;
     bool full_update_gfx;
@@ -198,7 +197,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
 uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr);
 void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val);
 void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
-void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp);
 
 int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
 
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 0d9a584..1ecee8f 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1119,31 +1119,6 @@ static void vmsvga_invalidate_display(void *opaque)
     s->invalidated = 1;
 }
 
-/* save the vga display in a PPM image even if no display is
-   available */
-static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch,
-                               Error **errp)
-{
-    struct vmsvga_state_s *s = opaque;
-    DisplaySurface *surface = qemu_console_surface(s->vga.con);
-
-    if (!s->enable) {
-        s->vga.screen_dump(&s->vga, filename, cswitch, errp);
-        return;
-    }
-
-    if (surface_bits_per_pixel(surface) == 32) {
-        DisplaySurface *ds = qemu_create_displaysurface_from(
-                                 surface_width(surface),
-                                 surface_height(surface),
-                                 32,
-                                 surface_stride(surface),
-                                 s->vga.vram_ptr, false);
-        ppm_save(filename, ds, errp);
-        g_free(ds);
-    }
-}
-
 static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
 {
     struct vmsvga_state_s *s = opaque;
@@ -1212,7 +1187,6 @@ static void vmsvga_init(struct vmsvga_state_s *s,
 
     s->vga.con = graphic_console_init(vmsvga_update_display,
                                       vmsvga_invalidate_display,
-                                      vmsvga_screen_dump,
                                       vmsvga_text_update, s);
 
     s->fifo_size = SVGA_FIFO_SIZE;
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 7c46a2f..0db2f84 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -1007,7 +1007,6 @@ wait_more:
     fb->c.con = graphic_console_init(xenfb_update,
                                      xenfb_invalidate,
                                      NULL,
-                                     NULL,
                                      fb);
     fb->have_console = 1;
 
diff --git a/include/ui/console.h b/include/ui/console.h
index 0dd66fd..d6e3e92 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -279,13 +279,10 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 
 typedef void (*graphic_hw_update_ptr)(void *);
 typedef void (*graphic_hw_invalidate_ptr)(void *);
-typedef void (*graphic_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
-                                       Error **errp);
 typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
 
 QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
                                   graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_screen_dump_ptr screen_dump,
                                   graphic_hw_text_update_ptr text_update,
                                   void *opaque);
 
diff --git a/ui/console.c b/ui/console.c
index 331d942..8893e8b 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -121,7 +121,6 @@ struct QemuConsole {
     /* Graphic console state.  */
     graphic_hw_update_ptr hw_update;
     graphic_hw_invalidate_ptr hw_invalidate;
-    graphic_hw_screen_dump_ptr hw_screen_dump;
     graphic_hw_text_update_ptr hw_text_update;
     void *hw;
     int g_width, g_height;
@@ -188,28 +187,65 @@ void graphic_hw_invalidate(QemuConsole *con)
     }
 }
 
-void qmp_screendump(const char *filename, Error **errp)
+static void ppm_save(const char *filename, struct DisplaySurface *ds,
+                     Error **errp)
 {
-    QemuConsole *previous_active_console;
-    bool cswitch;
-
-    previous_active_console = active_console;
-    cswitch = previous_active_console && previous_active_console->index != 0;
+    int width = pixman_image_get_width(ds->image);
+    int height = pixman_image_get_height(ds->image);
+    FILE *f;
+    int y;
+    int ret;
+    pixman_image_t *linebuf;
 
-    /* There is currently no way of specifying which screen we want to dump,
-       so always dump the first one.  */
-    if (cswitch) {
-        console_select(0);
+    trace_ppm_save(filename, ds);
+    f = fopen(filename, "wb");
+    if (!f) {
+        error_setg(errp, "failed to open file '%s': %s", filename,
+                   strerror(errno));
+        return;
     }
-    if (consoles[0] && consoles[0]->hw_screen_dump) {
-        consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
-    } else {
-        error_setg(errp, "device doesn't support screendump");
+    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
+    if (ret < 0) {
+        linebuf = NULL;
+        goto write_err;
+    }
+    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
+    for (y = 0; y < height; y++) {
+        qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
+        clearerr(f);
+        ret = fwrite(pixman_image_get_data(linebuf), 1,
+                     pixman_image_get_stride(linebuf), f);
+        (void)ret;
+        if (ferror(f)) {
+            goto write_err;
+        }
     }
 
-    if (cswitch) {
-        console_select(previous_active_console->index);
+out:
+    qemu_pixman_image_unref(linebuf);
+    fclose(f);
+    return;
+
+write_err:
+    error_setg(errp, "failed to write to file '%s': %s", filename,
+               strerror(errno));
+    unlink(filename);
+    goto out;
+}
+
+void qmp_screendump(const char *filename, Error **errp)
+{
+    QemuConsole *con = consoles[0];
+    DisplaySurface *surface;
+
+    if (con == NULL) {
+        error_setg(errp, "There is no QemuConsole I can screendump from.");
+        return;
     }
+
+    graphic_hw_update(con);
+    surface = qemu_console_surface(con);
+    ppm_save(filename, surface, errp);
 }
 
 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
@@ -1411,7 +1447,6 @@ DisplayState *init_displaystate(void)
 
 QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
                                   graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_screen_dump_ptr screen_dump,
                                   graphic_hw_text_update_ptr text_update,
                                   void *opaque)
 {
@@ -1425,7 +1460,6 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
     s = new_console(ds, GRAPHIC_CONSOLE);
     s->hw_update = update;
     s->hw_invalidate = invalidate;
-    s->hw_screen_dump = screen_dump;
     s->hw_text_update = text_update;
     s->hw = opaque;
 
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 15/24] console: zap g_width + g_height
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (13 preceding siblings ...)
  2013-04-04  7:28   ` Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 16/24] console: move gui_update+gui_setup_refresh from vl.c into console.c Gerd Hoffmann
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

We have a surface per QemuConsole now, so there is no need to keep
track of the QemuConsole size any more as we can query the surface
size directly at any time.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c |   32 +++++++++-----------------------
 1 file changed, 9 insertions(+), 23 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index 8893e8b..29e9f43 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -123,7 +123,6 @@ struct QemuConsole {
     graphic_hw_invalidate_ptr hw_invalidate;
     graphic_hw_text_update_ptr hw_text_update;
     void *hw;
-    int g_width, g_height;
 
     /* Text console state */
     int width;
@@ -389,8 +388,8 @@ static void text_console_resize(QemuConsole *s)
     int w1, x, y, last_width;
 
     last_width = s->width;
-    s->width = s->g_width / FONT_WIDTH;
-    s->height = s->g_height / FONT_HEIGHT;
+    s->width = surface_width(s->surface) / FONT_WIDTH;
+    s->height = surface_height(s->surface) / FONT_HEIGHT;
 
     w1 = last_width;
     if (s->width < w1)
@@ -951,18 +950,12 @@ static void console_putchar(QemuConsole *s, int ch)
 
 void console_select(unsigned int index)
 {
-    DisplaySurface *surface;
     QemuConsole *s;
 
     if (index >= MAX_CONSOLES)
         return;
 
     trace_console_select(index);
-    if (active_console) {
-        surface = qemu_console_surface(active_console);
-        active_console->g_width = surface_width(surface);
-        active_console->g_height = surface_height(surface);
-    }
     s = consoles[index];
     if (s) {
         DisplayState *ds = s->ds;
@@ -1089,11 +1082,8 @@ void kbd_put_keysym(int keysym)
 static void text_console_invalidate(void *opaque)
 {
     QemuConsole *s = (QemuConsole *) opaque;
-    DisplaySurface *surface = qemu_console_surface(s);
 
     if (s->ds->have_text && s->console_type == TEXT_CONSOLE) {
-        s->g_width = surface_width(surface);
-        s->g_height = surface_height(surface);
         text_console_resize(s);
     }
     console_refresh(s);
@@ -1497,6 +1487,8 @@ static void text_console_update_cursor(void *opaque)
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 {
     QemuConsole *s;
+    int g_width = 80 * FONT_WIDTH;
+    int g_height = 24 * FONT_HEIGHT;
 
     s = chr->opaque;
 
@@ -1512,16 +1504,13 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
     s->total_height = DEFAULT_BACKSCROLL;
     s->x = 0;
     s->y = 0;
-    if (s->console_type == TEXT_CONSOLE) {
+    if (!s->surface) {
         if (active_console && active_console->surface) {
-            s->g_width = surface_width(active_console->surface);
-            s->g_height = surface_height(active_console->surface);
-        } else {
-            s->g_width = 80 * FONT_WIDTH;
-            s->g_height = 24 * FONT_HEIGHT;
+            g_width = surface_width(active_console->surface);
+            g_height = surface_height(active_console->surface);
         }
+        s->surface = qemu_create_displaysurface(g_width, g_height);
     }
-    s->surface = qemu_create_displaysurface(s->g_width, s->g_height);
 
     s->cursor_timer =
         qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
@@ -1583,6 +1572,7 @@ static CharDriverState *text_console_init(ChardevVC *vc)
         s = new_console(NULL, TEXT_CONSOLE);
     } else {
         s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE);
+        s->surface = qemu_create_displaysurface(width, height);
     }
 
     if (!s) {
@@ -1591,8 +1581,6 @@ static CharDriverState *text_console_init(ChardevVC *vc)
     }
 
     s->chr = chr;
-    s->g_width = width;
-    s->g_height = height;
     chr->opaque = s;
     chr->chr_set_echo = text_console_set_echo;
 
@@ -1619,8 +1607,6 @@ void qemu_console_resize(QemuConsole *s, int width, int height)
     DisplaySurface *surface;
 
     assert(s->console_type == GRAPHIC_CONSOLE);
-    s->g_width = width;
-    s->g_height = height;
     surface = qemu_create_displaysurface(width, height);
     dpy_gfx_replace_surface(s, surface);
 }
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 16/24] console: move gui_update+gui_setup_refresh from vl.c into console.c
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (14 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 15/24] console: zap g_width + g_height Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 17/24] console: make DisplayState private to console.c Gerd Hoffmann
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Pure code motion, no functional changes.

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

diff --git a/include/ui/console.h b/include/ui/console.h
index d6e3e92..d92626b 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -213,8 +213,6 @@ static inline int is_buffer_shared(DisplaySurface *surface)
     return !(surface->flags & QEMU_ALLOCATED_FLAG);
 }
 
-void gui_setup_refresh(DisplayState *ds);
-
 void register_displaychangelistener(DisplayState *ds,
                                     DisplayChangeListener *dcl);
 void unregister_displaychangelistener(DisplayChangeListener *dcl);
diff --git a/ui/console.c b/ui/console.c
index 29e9f43..1ca50fc 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -166,6 +166,56 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
 static void dpy_gfx_switch_surface(DisplayState *ds,
                                    DisplaySurface *surface);
 
+static void gui_update(void *opaque)
+{
+    uint64_t interval = GUI_REFRESH_INTERVAL;
+    DisplayState *ds = opaque;
+    DisplayChangeListener *dcl;
+
+    dpy_refresh(ds);
+
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
+        if (dcl->gui_timer_interval &&
+            dcl->gui_timer_interval < interval) {
+            interval = dcl->gui_timer_interval;
+        }
+    }
+    qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
+}
+
+static 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->ops->dpy_refresh != NULL) {
+            need_timer = true;
+        }
+        if (dcl->ops->dpy_gfx_update != NULL) {
+            have_gfx = true;
+        }
+        if (dcl->ops->dpy_text_update != NULL) {
+            have_text = true;
+        }
+    }
+
+    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;
+    }
+
+    ds->have_gfx = have_gfx;
+    ds->have_text = have_text;
+}
+
 void graphic_hw_update(QemuConsole *con)
 {
     if (!con) {
diff --git a/vl.c b/vl.c
index b05c289..ebba472 100644
--- a/vl.c
+++ b/vl.c
@@ -1630,55 +1630,6 @@ MachineInfoList *qmp_query_machines(Error **errp)
 /***********************************************************/
 /* main execution loop */
 
-static void gui_update(void *opaque)
-{
-    uint64_t interval = GUI_REFRESH_INTERVAL;
-    DisplayState *ds = opaque;
-    DisplayChangeListener *dcl;
-
-    dpy_refresh(ds);
-
-    QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->gui_timer_interval &&
-            dcl->gui_timer_interval < interval)
-            interval = dcl->gui_timer_interval;
-    }
-    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;
-    bool have_gfx = false;
-    bool have_text = false;
-
-    QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->ops->dpy_refresh != NULL) {
-            need_timer = true;
-        }
-        if (dcl->ops->dpy_gfx_update != NULL) {
-            have_gfx = true;
-        }
-        if (dcl->ops->dpy_text_update != NULL) {
-            have_text = true;
-        }
-    }
-
-    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;
-    }
-
-    ds->have_gfx = have_gfx;
-    ds->have_text = have_text;
-}
-
 struct vm_change_state_entry {
     VMChangeStateHandler *cb;
     void *opaque;
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 17/24] console: make DisplayState private to console.c
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (15 preceding siblings ...)
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 16/24] console: move gui_update+gui_setup_refresh from vl.c into console.c Gerd Hoffmann
@ 2013-04-04  7:28 ` Gerd Hoffmann
  2013-04-04  7:29   ` Gerd Hoffmann
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

With gui_* being moved to console.c nobody outside console.c needs
access to DisplayState fields any more.  Make the struct private.

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

diff --git a/include/ui/console.h b/include/ui/console.h
index d92626b..50cd7b0 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -182,14 +182,6 @@ struct DisplayChangeListener {
     QLIST_ENTRY(DisplayChangeListener) next;
 };
 
-struct DisplayState {
-    struct QEMUTimer *gui_timer;
-    bool have_gfx;
-    bool have_text;
-
-    QLIST_HEAD(, DisplayChangeListener) listeners;
-};
-
 DisplayState *init_displaystate(void);
 DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data,
diff --git a/ui/console.c b/ui/console.c
index 1ca50fc..ea8c218 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -157,6 +157,14 @@ struct QemuConsole {
     QEMUTimer *kbd_timer;
 };
 
+struct DisplayState {
+    struct QEMUTimer *gui_timer;
+    bool have_gfx;
+    bool have_text;
+
+    QLIST_HEAD(, DisplayChangeListener) listeners;
+};
+
 static DisplayState *display_state;
 static QemuConsole *active_console;
 static QemuConsole *consoles[MAX_CONSOLES];
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 18/24] console: add GraphicHwOps
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
@ 2013-04-04  7:29   ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
                     ` (22 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Guan Xuetao, Igor Mitsyanko,
	Evgeny Voevodin, Stefano Stabellini, open list:X86,
	Gerd Hoffmann, Maksim Kozlov, Dmitry Solodkiy

Pass a single GraphicHwOps struct pointer to graphic_console_init,
instead of a bunch of function pointers.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/arm/musicpal.c    |    8 ++++++--
 hw/blizzard.c        |    9 ++++++---
 hw/cirrus_vga.c      |    8 ++------
 hw/exynos4210_fimd.c |    8 ++++++--
 hw/g364fb.c          |    9 ++++++---
 hw/jazz_led.c        |   10 +++++++---
 hw/milkymist-vgafb.c |    9 ++++++---
 hw/omap_lcdc.c       |    9 ++++++---
 hw/pl110.c           |    9 ++++++---
 hw/pxa2xx_lcd.c      |    9 ++++++---
 hw/qxl.c             |   16 ++++++++++------
 hw/sm501.c           |    7 +++++--
 hw/ssd0303.c         |    9 ++++++---
 hw/ssd0323.c         |    9 ++++++---
 hw/tc6393xb.c        |    9 +++++----
 hw/tcx.c             |   18 ++++++++++++------
 hw/unicore32/puv3.c  |    4 +++-
 hw/vga-isa-mm.c      |    4 +---
 hw/vga-isa.c         |    3 +--
 hw/vga-pci.c         |    3 +--
 hw/vga.c             |   10 +++++++---
 hw/vga_int.h         |    4 +---
 hw/vmware_vga.c      |   20 ++++++++++++--------
 hw/xenfb.c           |   10 ++++++----
 include/ui/console.h |   12 ++++++------
 ui/console.c         |   33 ++++++++++++++++-----------------
 26 files changed, 155 insertions(+), 104 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 0258373..61cbb5c 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -601,6 +601,11 @@ static const MemoryRegionOps musicpal_lcd_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static const GraphicHwOps musicpal_gfx_ops = {
+    .invalidate  = lcd_invalidate,
+    .gfx_update  = lcd_refresh,
+};
+
 static int musicpal_lcd_init(SysBusDevice *dev)
 {
     musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev);
@@ -611,8 +616,7 @@ static int musicpal_lcd_init(SysBusDevice *dev)
                           "musicpal-lcd", MP_LCD_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
 
-    s->con = graphic_console_init(lcd_refresh, lcd_invalidate,
-                                  NULL, s);
+    s->con = graphic_console_init(&musicpal_gfx_ops, s);
     qemu_console_resize(s->con, 128*3, 64*3);
 
     qdev_init_gpio_in(&dev->qdev, musicpal_lcd_gpio_brigthness_in, 3);
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 891bff8..794b276 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -944,6 +944,11 @@ static void blizzard_update_display(void *opaque)
 #define DEPTH 32
 #include "hw/blizzard_template.h"
 
+static const GraphicHwOps blizzard_ops = {
+    .invalidate  = blizzard_invalidate_display,
+    .gfx_update  = blizzard_update_display,
+};
+
 void *s1d13745_init(qemu_irq gpio_int)
 {
     BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s));
@@ -951,9 +956,7 @@ void *s1d13745_init(qemu_irq gpio_int)
 
     s->fb = g_malloc(0x180000);
 
-    s->con = graphic_console_init(blizzard_update_display,
-                                  blizzard_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&blizzard_ops, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 03b3245..ed7962f 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2910,9 +2910,7 @@ static int vga_initfn(ISADevice *dev)
     vga_common_init(s);
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
                        isa_address_space(dev), isa_address_space_io(dev));
-    s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->text_update,
-                                  s);
+    s->con = graphic_console_init(s->hw_ops, s);
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
     /* XXX ISA-LFB support */
     /* FIXME not qdev yet */
@@ -2959,9 +2957,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
      vga_common_init(&s->vga);
      cirrus_init_common(s, device_id, 1, pci_address_space(dev),
                         pci_address_space_io(dev));
-     s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                       s->vga.text_update,
-                                       &s->vga);
+     s->vga.con = graphic_console_init(s->vga.hw_ops, &s->vga);
 
      /* setup PCI */
 
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 8178917..b92922a 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1888,6 +1888,11 @@ static const VMStateDescription exynos4210_fimd_vmstate = {
     }
 };
 
+static const GraphicHwOps exynos4210_fimd_ops = {
+    .invalidate  = exynos4210_fimd_invalidate,
+    .gfx_update  = exynos4210_fimd_update,
+};
+
 static int exynos4210_fimd_init(SysBusDevice *dev)
 {
     Exynos4210fimdState *s = FROM_SYSBUS(Exynos4210fimdState, dev);
@@ -1901,8 +1906,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
     memory_region_init_io(&s->iomem, &exynos4210_fimd_mmio_ops, s,
             "exynos4210.fimd", FIMD_REGS_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
-    s->console = graphic_console_init(exynos4210_fimd_update,
-                                      exynos4210_fimd_invalidate, NULL, s);
+    s->console = graphic_console_init(&exynos4210_fimd_ops, s);
 
     return 0;
 }
diff --git a/hw/g364fb.c b/hw/g364fb.c
index b70fe8a..03810e9 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -475,13 +475,16 @@ static const VMStateDescription vmstate_g364fb = {
     }
 };
 
+static const GraphicHwOps g364fb_ops = {
+    .invalidate  = g364fb_invalidate_display,
+    .gfx_update  = g364fb_update_display,
+};
+
 static void g364fb_init(DeviceState *dev, G364State *s)
 {
     s->vram = g_malloc0(s->vram_size);
 
-    s->con = graphic_console_init(g364fb_update_display,
-                                  g364fb_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&g364fb_ops, s);
 
     memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
     memory_region_init_ram_ptr(&s->mem_vram, "vram",
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index c027f76..6306d8c 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -254,6 +254,12 @@ static const VMStateDescription vmstate_jazz_led = {
     }
 };
 
+static const GraphicHwOps jazz_led_ops = {
+    .invalidate  = jazz_led_invalidate_display,
+    .gfx_update  = jazz_led_update_display,
+    .text_update = jazz_led_text_update,
+};
+
 static int jazz_led_init(SysBusDevice *dev)
 {
     LedState *s = FROM_SYSBUS(LedState, dev);
@@ -261,9 +267,7 @@ static int jazz_led_init(SysBusDevice *dev)
     memory_region_init_io(&s->iomem, &led_ops, s, "led", 1);
     sysbus_init_mmio(dev, &s->iomem);
 
-    s->con = graphic_console_init(jazz_led_update_display,
-                                  jazz_led_invalidate_display,
-                                  jazz_led_text_update, s);
+    s->con = graphic_console_init(&jazz_led_ops, s);
 
     return 0;
 }
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 80486e8..91c80c5 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -270,6 +270,11 @@ static void milkymist_vgafb_reset(DeviceState *d)
     s->regs[R_BASEADDRESS] = 0;
 }
 
+static const GraphicHwOps vgafb_ops = {
+    .invalidate  = vgafb_invalidate_display,
+    .gfx_update  = vgafb_update_display,
+};
+
 static int milkymist_vgafb_init(SysBusDevice *dev)
 {
     MilkymistVgafbState *s = FROM_SYSBUS(typeof(*s), dev);
@@ -278,9 +283,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
             "milkymist-vgafb", R_MAX * 4);
     sysbus_init_mmio(dev, &s->regs_region);
 
-    s->con = graphic_console_init(vgafb_update_display,
-                                  vgafb_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&vgafb_ops, s);
 
     return 0;
 }
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 1cb49d5..eb4073b 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -384,6 +384,11 @@ void omap_lcdc_reset(struct omap_lcd_panel_s *s)
     s->ctrl = 0;
 }
 
+static const GraphicHwOps omap_ops = {
+    .invalidate  = omap_invalidate_display,
+    .gfx_update  = omap_update_display,
+};
+
 struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
                                         hwaddr base,
                                         qemu_irq irq,
@@ -401,9 +406,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
     memory_region_init_io(&s->iomem, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
-    s->con = graphic_console_init(omap_update_display,
-                                  omap_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&omap_ops, s);
 
     return s;
 }
diff --git a/hw/pl110.c b/hw/pl110.c
index 6f24957..f80f297 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -444,6 +444,11 @@ static int vmstate_pl110_post_load(void *opaque, int version_id)
     return 0;
 }
 
+static const GraphicHwOps pl110_gfx_ops = {
+    .invalidate  = pl110_invalidate_display,
+    .gfx_update  = pl110_update_display,
+};
+
 static int pl110_init(SysBusDevice *dev)
 {
     pl110_state *s = FROM_SYSBUS(pl110_state, dev);
@@ -452,9 +457,7 @@ static int pl110_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
     qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
-    s->con = graphic_console_init(pl110_update_display,
-                                  pl110_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&pl110_gfx_ops, s);
     return 0;
 }
 
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 602e3dc..7d09e5e 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -991,6 +991,11 @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
 #define BITS 32
 #include "hw/pxa2xx_template.h"
 
+static const GraphicHwOps pxa2xx_ops = {
+    .invalidate  = pxa2xx_invalidate_display,
+    .gfx_update  = pxa2xx_update_display,
+};
+
 PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
                                  hwaddr base, qemu_irq irq)
 {
@@ -1008,9 +1013,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
                           "pxa2xx-lcd-controller", 0x00100000);
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
-    s->con = graphic_console_init(pxa2xx_update_display,
-                                  pxa2xx_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&pxa2xx_ops, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 0f09bae..36f18fd 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1753,7 +1753,7 @@ static void qxl_hw_update(void *opaque)
 
     switch (qxl->mode) {
     case QXL_MODE_VGA:
-        vga->update(vga);
+        vga->hw_ops->gfx_update(vga);
         break;
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
@@ -1769,7 +1769,7 @@ static void qxl_hw_invalidate(void *opaque)
     PCIQXLDevice *qxl = opaque;
     VGACommonState *vga = &qxl->vga;
 
-    vga->invalidate(vga);
+    vga->hw_ops->invalidate(vga);
 }
 
 static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
@@ -1778,7 +1778,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
     VGACommonState *vga = &qxl->vga;
 
     if (qxl->mode == QXL_MODE_VGA) {
-        vga->text_update(vga, chardata);
+        vga->hw_ops->text_update(vga, chardata);
         return;
     }
 }
@@ -2038,6 +2038,12 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     return 0;
 }
 
+static const GraphicHwOps qxl_ops = {
+    .invalidate  = qxl_hw_invalidate,
+    .gfx_update  = qxl_hw_update,
+    .text_update = qxl_hw_text_update,
+};
+
 static int qxl_init_primary(PCIDevice *dev)
 {
     PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
@@ -2054,9 +2060,7 @@ static int qxl_init_primary(PCIDevice *dev)
     portio_list_init(qxl_vga_port_list, qxl_vga_portio_list, vga, "vga");
     portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
 
-    vga->con = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
-                                    qxl_hw_text_update,
-                                    qxl);
+    vga->con = graphic_console_init(&qxl_ops, qxl);
     qxl->ssd.con = vga->con,
     qemu_spice_display_init_common(&qxl->ssd);
 
diff --git a/hw/sm501.c b/hw/sm501.c
index 1f428cd..cf3bb11 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1383,6 +1383,10 @@ static void sm501_update_display(void *opaque)
 	sm501_draw_crt(s);
 }
 
+static const GraphicHwOps sm501_ops = {
+    .gfx_update  = sm501_update_display,
+};
+
 void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
                 uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr)
 {
@@ -1445,6 +1449,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
     }
 
     /* create qemu graphic console */
-    s->con = graphic_console_init(sm501_update_display, NULL,
-                                  NULL, s);
+    s->con = graphic_console_init(&sm501_ops, s);
 }
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 02feaff..9af8f75 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -284,13 +284,16 @@ static const VMStateDescription vmstate_ssd0303 = {
     }
 };
 
+static const GraphicHwOps ssd0303_ops = {
+    .invalidate  = ssd0303_invalidate_display,
+    .gfx_update  = ssd0303_update_display,
+};
+
 static int ssd0303_init(I2CSlave *i2c)
 {
     ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
 
-    s->con = graphic_console_init(ssd0303_update_display,
-                                  ssd0303_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&ssd0303_ops, s);
     qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
     return 0;
 }
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 301cb20..45e8dc1 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -331,15 +331,18 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
+static const GraphicHwOps ssd0323_ops = {
+    .invalidate  = ssd0323_invalidate_display,
+    .gfx_update  = ssd0323_update_display,
+};
+
 static int ssd0323_init(SSISlave *dev)
 {
     ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
 
     s->col_end = 63;
     s->row_end = 79;
-    s->con = graphic_console_init(ssd0323_update_display,
-                                  ssd0323_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&ssd0323_ops, s);
     qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 
     qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 30b624e..8eaccdb 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -548,6 +548,10 @@ static void tc6393xb_writeb(void *opaque, hwaddr addr,
                 (uint32_t) addr, (int)value & 0xff);
 }
 
+static const GraphicHwOps tc6393xb_gfx_ops = {
+    .gfx_update  = tc6393xb_update_display,
+};
+
 TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
 {
     TC6393xbState *s;
@@ -583,10 +587,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
     memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
     s->scr_width = 480;
     s->scr_height = 640;
-    s->con = graphic_console_init(tc6393xb_update_display,
-            NULL, /* invalidate */
-            NULL, /* text_update */
-            s);
+    s->con = graphic_console_init(&tc6393xb_gfx_ops, s);
 
     return s;
 }
diff --git a/hw/tcx.c b/hw/tcx.c
index ba3857a..77c7191 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -510,6 +510,16 @@ static const MemoryRegionOps dummy_ops = {
     },
 };
 
+static const GraphicHwOps tcx_ops = {
+    .invalidate = tcx_invalidate_display,
+    .gfx_update = tcx_update_display,
+};
+
+static const GraphicHwOps tcx24_ops = {
+    .invalidate = tcx24_invalidate_display,
+    .gfx_update = tcx24_update_display,
+};
+
 static int tcx_init1(SysBusDevice *dev)
 {
     TCXState *s = FROM_SYSBUS(TCXState, dev);
@@ -562,18 +572,14 @@ static int tcx_init1(SysBusDevice *dev)
                                  &s->vram_mem, vram_offset, size);
         sysbus_init_mmio(dev, &s->vram_cplane);
 
-        s->con = graphic_console_init(tcx24_update_display,
-                                      tcx24_invalidate_display,
-                                      NULL, s);
+        s->con = graphic_console_init(&tcx24_ops, s);
     } else {
         /* THC 8 bit (dummy) */
         memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
                               TCX_THC_NREGS_8);
         sysbus_init_mmio(dev, &s->thc8);
 
-        s->con = graphic_console_init(tcx_update_display,
-                                      tcx_invalidate_display,
-                                      NULL, s);
+        s->con = graphic_console_init(&tcx_ops, s);
     }
 
     qemu_console_resize(s->con, s->width, s->height);
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index d110363..20356b5 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -78,6 +78,8 @@ static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
     memory_region_add_subregion(get_system_memory(), 0, ram_memory);
 }
 
+static const GraphicHwOps no_ops;
+
 static void puv3_load_kernel(const char *kernel_filename)
 {
     int size;
@@ -92,7 +94,7 @@ static void puv3_load_kernel(const char *kernel_filename)
     }
 
     /* cheat curses that we have a graphic console, only under ocd console */
-    graphic_console_init(NULL, NULL, NULL, NULL);
+    graphic_console_init(&no_ops, NULL);
 }
 
 static void puv3_init(QEMUMachineInitArgs *args)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 5fb04fb..3f3af9a 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -135,9 +135,7 @@ int isa_vga_mm_init(hwaddr vram_base,
     vga_common_init(&s->vga);
     vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
 
-    s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                      s->vga.text_update,
-                                      s);
+    s->vga.con = graphic_console_init(s->vga.hw_ops, s);
 
     vga_init_vbe(&s->vga, address_space);
     return 0;
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 0a1aded..a76cef2 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -62,8 +62,7 @@ static int vga_initfn(ISADevice *dev)
                                         isa_mem_base + 0x000a0000,
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
-    s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->text_update, s);
+    s->con = graphic_console_init(s->hw_ops, s);
 
     vga_init_vbe(s, isa_address_space(dev));
     /* ROM BIOS */
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index a982f2a..5ffc37b 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -150,8 +150,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
     vga_common_init(s);
     vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
 
-    s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->text_update, s);
+    s->con = graphic_console_init(s->hw_ops, s);
 
     /* XXX: VGA_RAM_SIZE must be a power of two */
     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
diff --git a/hw/vga.c b/hw/vga.c
index a875faa..5c87754 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2250,6 +2250,12 @@ const VMStateDescription vmstate_vga_common = {
     }
 };
 
+static const GraphicHwOps vga_ops = {
+    .invalidate  = vga_invalidate_display,
+    .gfx_update  = vga_update_display,
+    .text_update = vga_update_text,
+};
+
 void vga_common_init(VGACommonState *s)
 {
     int i, j, v, b;
@@ -2293,9 +2299,7 @@ void vga_common_init(VGACommonState *s)
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
     s->get_resolution = vga_get_resolution;
-    s->update = vga_update_display;
-    s->invalidate = vga_invalidate_display;
-    s->text_update = vga_update_text;
+    s->hw_ops = &vga_ops;
     switch (vga_retrace_method) {
     case VGA_RETRACE_DUMB:
         s->retrace = vga_dumb_retrace;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index e4bb4a0..66f9f3c 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -152,9 +152,7 @@ typedef struct VGACommonState {
     uint32_t cursor_offset;
     unsigned int (*rgb_to_pixel)(unsigned int r,
                                  unsigned int g, unsigned b);
-    graphic_hw_update_ptr update;
-    graphic_hw_invalidate_ptr invalidate;
-    graphic_hw_text_update_ptr text_update;
+    const GraphicHwOps *hw_ops;
     bool full_update_text;
     bool full_update_gfx;
     /* hardware mouse cursor support */
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 1ecee8f..c330e96 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -913,7 +913,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
     case SVGA_REG_ENABLE:
         s->enable = !!value;
         s->invalidated = 1;
-        s->vga.invalidate(&s->vga);
+        s->vga.hw_ops->invalidate(&s->vga);
         if (s->enable && s->config) {
             vga_dirty_log_stop(&s->vga);
         } else {
@@ -1058,7 +1058,7 @@ static void vmsvga_update_display(void *opaque)
     bool dirty = false;
 
     if (!s->enable) {
-        s->vga.update(&s->vga);
+        s->vga.hw_ops->gfx_update(&s->vga);
         return;
     }
 
@@ -1112,7 +1112,7 @@ static void vmsvga_invalidate_display(void *opaque)
 {
     struct vmsvga_state_s *s = opaque;
     if (!s->enable) {
-        s->vga.invalidate(&s->vga);
+        s->vga.hw_ops->invalidate(&s->vga);
         return;
     }
 
@@ -1123,8 +1123,8 @@ static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
 {
     struct vmsvga_state_s *s = opaque;
 
-    if (s->vga.text_update) {
-        s->vga.text_update(&s->vga, chardata);
+    if (s->vga.hw_ops->text_update) {
+        s->vga.hw_ops->text_update(&s->vga, chardata);
     }
 }
 
@@ -1179,15 +1179,19 @@ static const VMStateDescription vmstate_vmware_vga = {
     }
 };
 
+static const GraphicHwOps vmsvga_ops = {
+    .invalidate  = vmsvga_invalidate_display,
+    .gfx_update  = vmsvga_update_display,
+    .text_update = vmsvga_text_update,
+};
+
 static void vmsvga_init(struct vmsvga_state_s *s,
                         MemoryRegion *address_space, MemoryRegion *io)
 {
     s->scratch_size = SVGA_SCRATCH_SIZE;
     s->scratch = g_malloc(s->scratch_size * 4);
 
-    s->vga.con = graphic_console_init(vmsvga_update_display,
-                                      vmsvga_invalidate_display,
-                                      vmsvga_text_update, s);
+    s->vga.con = graphic_console_init(&vmsvga_ops, s);
 
     s->fifo_size = SVGA_FIFO_SIZE;
     memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size);
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 0db2f84..f2af7eb 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -977,6 +977,11 @@ struct XenDevOps xen_framebuffer_ops = {
     .frontend_changed = fb_frontend_changed,
 };
 
+static const GraphicHwOps xenfb_ops = {
+    .invalidate  = xenfb_invalidate,
+    .gfx_update  = xenfb_update,
+};
+
 /*
  * FIXME/TODO: Kill this.
  * Temporary needed while DisplayState reorganization is in flight.
@@ -1004,10 +1009,7 @@ wait_more:
 
     /* vfb */
     fb = container_of(xfb, struct XenFB, c.xendev);
-    fb->c.con = graphic_console_init(xenfb_update,
-                                     xenfb_invalidate,
-                                     NULL,
-                                     fb);
+    fb->c.con = graphic_console_init(&xenfb_ops, fb);
     fb->have_console = 1;
 
     /* vkbd */
diff --git a/include/ui/console.h b/include/ui/console.h
index 50cd7b0..f3e7791 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -267,13 +267,13 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
     *dest = ch;
 }
 
-typedef void (*graphic_hw_update_ptr)(void *);
-typedef void (*graphic_hw_invalidate_ptr)(void *);
-typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
+typedef struct GraphicHwOps {
+    void (*invalidate)(void *opaque);
+    void (*gfx_update)(void *opaque);
+    void (*text_update)(void *opaque, console_ch_t *text);
+} GraphicHwOps;
 
-QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
-                                  graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(const GraphicHwOps *ops,
                                   void *opaque);
 
 void graphic_hw_update(QemuConsole *con);
diff --git a/ui/console.c b/ui/console.c
index ea8c218..49ed6ef 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -119,9 +119,7 @@ struct QemuConsole {
     DisplaySurface *surface;
 
     /* Graphic console state.  */
-    graphic_hw_update_ptr hw_update;
-    graphic_hw_invalidate_ptr hw_invalidate;
-    graphic_hw_text_update_ptr hw_text_update;
+    const GraphicHwOps *hw_ops;
     void *hw;
 
     /* Text console state */
@@ -229,8 +227,8 @@ void graphic_hw_update(QemuConsole *con)
     if (!con) {
         con = active_console;
     }
-    if (con && con->hw_update) {
-        con->hw_update(con->hw);
+    if (con && con->hw_ops->gfx_update) {
+        con->hw_ops->gfx_update(con->hw);
     }
 }
 
@@ -239,8 +237,8 @@ void graphic_hw_invalidate(QemuConsole *con)
     if (!con) {
         con = active_console;
     }
-    if (con && con->hw_invalidate) {
-        con->hw_invalidate(con->hw);
+    if (con && con->hw_ops->invalidate) {
+        con->hw_ops->invalidate(con->hw);
     }
 }
 
@@ -310,8 +308,9 @@ void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
     if (!con) {
         con = active_console;
     }
-    if (con && con->hw_text_update)
-        con->hw_text_update(con->hw, chardata);
+    if (con && con->hw_ops->text_update) {
+        con->hw_ops->text_update(con->hw, chardata);
+    }
 }
 
 static void vga_fill_rect(QemuConsole *con,
@@ -1493,9 +1492,7 @@ DisplayState *init_displaystate(void)
     return display_state;
 }
 
-QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
-                                  graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(const GraphicHwOps *hw_ops,
                                   void *opaque)
 {
     int width = 640;
@@ -1506,9 +1503,7 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
     ds = get_alloc_displaystate();
     trace_console_gfx_new();
     s = new_console(ds, GRAPHIC_CONSOLE);
-    s->hw_update = update;
-    s->hw_invalidate = invalidate;
-    s->hw_text_update = text_update;
+    s->hw_ops = hw_ops;
     s->hw = opaque;
 
     s->surface = qemu_create_displaysurface(width, height);
@@ -1542,6 +1537,11 @@ static void text_console_update_cursor(void *opaque)
                    qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
 }
 
+static const GraphicHwOps text_console_ops = {
+    .invalidate  = text_console_invalidate,
+    .text_update = text_console_update,
+};
+
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 {
     QemuConsole *s;
@@ -1573,8 +1573,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
     s->cursor_timer =
         qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
 
-    s->hw_invalidate = text_console_invalidate;
-    s->hw_text_update = text_console_update;
+    s->hw_ops = &text_console_ops;
     s->hw = s;
 
     /* Set text attribute defaults */
-- 
1.7.9.7

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

* [PATCH 18/24] console: add GraphicHwOps
@ 2013-04-04  7:29   ` Gerd Hoffmann
  0 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Guan Xuetao, Igor Mitsyanko,
	Evgeny Voevodin, Stefano Stabellini, open list:X86,
	Gerd Hoffmann, Maksim Kozlov, Dmitry Solodkiy

Pass a single GraphicHwOps struct pointer to graphic_console_init,
instead of a bunch of function pointers.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/arm/musicpal.c    |    8 ++++++--
 hw/blizzard.c        |    9 ++++++---
 hw/cirrus_vga.c      |    8 ++------
 hw/exynos4210_fimd.c |    8 ++++++--
 hw/g364fb.c          |    9 ++++++---
 hw/jazz_led.c        |   10 +++++++---
 hw/milkymist-vgafb.c |    9 ++++++---
 hw/omap_lcdc.c       |    9 ++++++---
 hw/pl110.c           |    9 ++++++---
 hw/pxa2xx_lcd.c      |    9 ++++++---
 hw/qxl.c             |   16 ++++++++++------
 hw/sm501.c           |    7 +++++--
 hw/ssd0303.c         |    9 ++++++---
 hw/ssd0323.c         |    9 ++++++---
 hw/tc6393xb.c        |    9 +++++----
 hw/tcx.c             |   18 ++++++++++++------
 hw/unicore32/puv3.c  |    4 +++-
 hw/vga-isa-mm.c      |    4 +---
 hw/vga-isa.c         |    3 +--
 hw/vga-pci.c         |    3 +--
 hw/vga.c             |   10 +++++++---
 hw/vga_int.h         |    4 +---
 hw/vmware_vga.c      |   20 ++++++++++++--------
 hw/xenfb.c           |   10 ++++++----
 include/ui/console.h |   12 ++++++------
 ui/console.c         |   33 ++++++++++++++++-----------------
 26 files changed, 155 insertions(+), 104 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 0258373..61cbb5c 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -601,6 +601,11 @@ static const MemoryRegionOps musicpal_lcd_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static const GraphicHwOps musicpal_gfx_ops = {
+    .invalidate  = lcd_invalidate,
+    .gfx_update  = lcd_refresh,
+};
+
 static int musicpal_lcd_init(SysBusDevice *dev)
 {
     musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev);
@@ -611,8 +616,7 @@ static int musicpal_lcd_init(SysBusDevice *dev)
                           "musicpal-lcd", MP_LCD_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
 
-    s->con = graphic_console_init(lcd_refresh, lcd_invalidate,
-                                  NULL, s);
+    s->con = graphic_console_init(&musicpal_gfx_ops, s);
     qemu_console_resize(s->con, 128*3, 64*3);
 
     qdev_init_gpio_in(&dev->qdev, musicpal_lcd_gpio_brigthness_in, 3);
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 891bff8..794b276 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -944,6 +944,11 @@ static void blizzard_update_display(void *opaque)
 #define DEPTH 32
 #include "hw/blizzard_template.h"
 
+static const GraphicHwOps blizzard_ops = {
+    .invalidate  = blizzard_invalidate_display,
+    .gfx_update  = blizzard_update_display,
+};
+
 void *s1d13745_init(qemu_irq gpio_int)
 {
     BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s));
@@ -951,9 +956,7 @@ void *s1d13745_init(qemu_irq gpio_int)
 
     s->fb = g_malloc(0x180000);
 
-    s->con = graphic_console_init(blizzard_update_display,
-                                  blizzard_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&blizzard_ops, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 03b3245..ed7962f 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2910,9 +2910,7 @@ static int vga_initfn(ISADevice *dev)
     vga_common_init(s);
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
                        isa_address_space(dev), isa_address_space_io(dev));
-    s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->text_update,
-                                  s);
+    s->con = graphic_console_init(s->hw_ops, s);
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
     /* XXX ISA-LFB support */
     /* FIXME not qdev yet */
@@ -2959,9 +2957,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
      vga_common_init(&s->vga);
      cirrus_init_common(s, device_id, 1, pci_address_space(dev),
                         pci_address_space_io(dev));
-     s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                       s->vga.text_update,
-                                       &s->vga);
+     s->vga.con = graphic_console_init(s->vga.hw_ops, &s->vga);
 
      /* setup PCI */
 
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 8178917..b92922a 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1888,6 +1888,11 @@ static const VMStateDescription exynos4210_fimd_vmstate = {
     }
 };
 
+static const GraphicHwOps exynos4210_fimd_ops = {
+    .invalidate  = exynos4210_fimd_invalidate,
+    .gfx_update  = exynos4210_fimd_update,
+};
+
 static int exynos4210_fimd_init(SysBusDevice *dev)
 {
     Exynos4210fimdState *s = FROM_SYSBUS(Exynos4210fimdState, dev);
@@ -1901,8 +1906,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
     memory_region_init_io(&s->iomem, &exynos4210_fimd_mmio_ops, s,
             "exynos4210.fimd", FIMD_REGS_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
-    s->console = graphic_console_init(exynos4210_fimd_update,
-                                      exynos4210_fimd_invalidate, NULL, s);
+    s->console = graphic_console_init(&exynos4210_fimd_ops, s);
 
     return 0;
 }
diff --git a/hw/g364fb.c b/hw/g364fb.c
index b70fe8a..03810e9 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -475,13 +475,16 @@ static const VMStateDescription vmstate_g364fb = {
     }
 };
 
+static const GraphicHwOps g364fb_ops = {
+    .invalidate  = g364fb_invalidate_display,
+    .gfx_update  = g364fb_update_display,
+};
+
 static void g364fb_init(DeviceState *dev, G364State *s)
 {
     s->vram = g_malloc0(s->vram_size);
 
-    s->con = graphic_console_init(g364fb_update_display,
-                                  g364fb_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&g364fb_ops, s);
 
     memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
     memory_region_init_ram_ptr(&s->mem_vram, "vram",
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index c027f76..6306d8c 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -254,6 +254,12 @@ static const VMStateDescription vmstate_jazz_led = {
     }
 };
 
+static const GraphicHwOps jazz_led_ops = {
+    .invalidate  = jazz_led_invalidate_display,
+    .gfx_update  = jazz_led_update_display,
+    .text_update = jazz_led_text_update,
+};
+
 static int jazz_led_init(SysBusDevice *dev)
 {
     LedState *s = FROM_SYSBUS(LedState, dev);
@@ -261,9 +267,7 @@ static int jazz_led_init(SysBusDevice *dev)
     memory_region_init_io(&s->iomem, &led_ops, s, "led", 1);
     sysbus_init_mmio(dev, &s->iomem);
 
-    s->con = graphic_console_init(jazz_led_update_display,
-                                  jazz_led_invalidate_display,
-                                  jazz_led_text_update, s);
+    s->con = graphic_console_init(&jazz_led_ops, s);
 
     return 0;
 }
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 80486e8..91c80c5 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -270,6 +270,11 @@ static void milkymist_vgafb_reset(DeviceState *d)
     s->regs[R_BASEADDRESS] = 0;
 }
 
+static const GraphicHwOps vgafb_ops = {
+    .invalidate  = vgafb_invalidate_display,
+    .gfx_update  = vgafb_update_display,
+};
+
 static int milkymist_vgafb_init(SysBusDevice *dev)
 {
     MilkymistVgafbState *s = FROM_SYSBUS(typeof(*s), dev);
@@ -278,9 +283,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
             "milkymist-vgafb", R_MAX * 4);
     sysbus_init_mmio(dev, &s->regs_region);
 
-    s->con = graphic_console_init(vgafb_update_display,
-                                  vgafb_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&vgafb_ops, s);
 
     return 0;
 }
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 1cb49d5..eb4073b 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -384,6 +384,11 @@ void omap_lcdc_reset(struct omap_lcd_panel_s *s)
     s->ctrl = 0;
 }
 
+static const GraphicHwOps omap_ops = {
+    .invalidate  = omap_invalidate_display,
+    .gfx_update  = omap_update_display,
+};
+
 struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
                                         hwaddr base,
                                         qemu_irq irq,
@@ -401,9 +406,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
     memory_region_init_io(&s->iomem, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
-    s->con = graphic_console_init(omap_update_display,
-                                  omap_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&omap_ops, s);
 
     return s;
 }
diff --git a/hw/pl110.c b/hw/pl110.c
index 6f24957..f80f297 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -444,6 +444,11 @@ static int vmstate_pl110_post_load(void *opaque, int version_id)
     return 0;
 }
 
+static const GraphicHwOps pl110_gfx_ops = {
+    .invalidate  = pl110_invalidate_display,
+    .gfx_update  = pl110_update_display,
+};
+
 static int pl110_init(SysBusDevice *dev)
 {
     pl110_state *s = FROM_SYSBUS(pl110_state, dev);
@@ -452,9 +457,7 @@ static int pl110_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
     qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
-    s->con = graphic_console_init(pl110_update_display,
-                                  pl110_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&pl110_gfx_ops, s);
     return 0;
 }
 
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 602e3dc..7d09e5e 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -991,6 +991,11 @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
 #define BITS 32
 #include "hw/pxa2xx_template.h"
 
+static const GraphicHwOps pxa2xx_ops = {
+    .invalidate  = pxa2xx_invalidate_display,
+    .gfx_update  = pxa2xx_update_display,
+};
+
 PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
                                  hwaddr base, qemu_irq irq)
 {
@@ -1008,9 +1013,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
                           "pxa2xx-lcd-controller", 0x00100000);
     memory_region_add_subregion(sysmem, base, &s->iomem);
 
-    s->con = graphic_console_init(pxa2xx_update_display,
-                                  pxa2xx_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&pxa2xx_ops, s);
     surface = qemu_console_surface(s->con);
 
     switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 0f09bae..36f18fd 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1753,7 +1753,7 @@ static void qxl_hw_update(void *opaque)
 
     switch (qxl->mode) {
     case QXL_MODE_VGA:
-        vga->update(vga);
+        vga->hw_ops->gfx_update(vga);
         break;
     case QXL_MODE_COMPAT:
     case QXL_MODE_NATIVE:
@@ -1769,7 +1769,7 @@ static void qxl_hw_invalidate(void *opaque)
     PCIQXLDevice *qxl = opaque;
     VGACommonState *vga = &qxl->vga;
 
-    vga->invalidate(vga);
+    vga->hw_ops->invalidate(vga);
 }
 
 static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
@@ -1778,7 +1778,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
     VGACommonState *vga = &qxl->vga;
 
     if (qxl->mode == QXL_MODE_VGA) {
-        vga->text_update(vga, chardata);
+        vga->hw_ops->text_update(vga, chardata);
         return;
     }
 }
@@ -2038,6 +2038,12 @@ static int qxl_init_common(PCIQXLDevice *qxl)
     return 0;
 }
 
+static const GraphicHwOps qxl_ops = {
+    .invalidate  = qxl_hw_invalidate,
+    .gfx_update  = qxl_hw_update,
+    .text_update = qxl_hw_text_update,
+};
+
 static int qxl_init_primary(PCIDevice *dev)
 {
     PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
@@ -2054,9 +2060,7 @@ static int qxl_init_primary(PCIDevice *dev)
     portio_list_init(qxl_vga_port_list, qxl_vga_portio_list, vga, "vga");
     portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
 
-    vga->con = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
-                                    qxl_hw_text_update,
-                                    qxl);
+    vga->con = graphic_console_init(&qxl_ops, qxl);
     qxl->ssd.con = vga->con,
     qemu_spice_display_init_common(&qxl->ssd);
 
diff --git a/hw/sm501.c b/hw/sm501.c
index 1f428cd..cf3bb11 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1383,6 +1383,10 @@ static void sm501_update_display(void *opaque)
 	sm501_draw_crt(s);
 }
 
+static const GraphicHwOps sm501_ops = {
+    .gfx_update  = sm501_update_display,
+};
+
 void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
                 uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr)
 {
@@ -1445,6 +1449,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
     }
 
     /* create qemu graphic console */
-    s->con = graphic_console_init(sm501_update_display, NULL,
-                                  NULL, s);
+    s->con = graphic_console_init(&sm501_ops, s);
 }
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 02feaff..9af8f75 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -284,13 +284,16 @@ static const VMStateDescription vmstate_ssd0303 = {
     }
 };
 
+static const GraphicHwOps ssd0303_ops = {
+    .invalidate  = ssd0303_invalidate_display,
+    .gfx_update  = ssd0303_update_display,
+};
+
 static int ssd0303_init(I2CSlave *i2c)
 {
     ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
 
-    s->con = graphic_console_init(ssd0303_update_display,
-                                  ssd0303_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&ssd0303_ops, s);
     qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
     return 0;
 }
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 301cb20..45e8dc1 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -331,15 +331,18 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
+static const GraphicHwOps ssd0323_ops = {
+    .invalidate  = ssd0323_invalidate_display,
+    .gfx_update  = ssd0323_update_display,
+};
+
 static int ssd0323_init(SSISlave *dev)
 {
     ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
 
     s->col_end = 63;
     s->row_end = 79;
-    s->con = graphic_console_init(ssd0323_update_display,
-                                  ssd0323_invalidate_display,
-                                  NULL, s);
+    s->con = graphic_console_init(&ssd0323_ops, s);
     qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
 
     qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 30b624e..8eaccdb 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -548,6 +548,10 @@ static void tc6393xb_writeb(void *opaque, hwaddr addr,
                 (uint32_t) addr, (int)value & 0xff);
 }
 
+static const GraphicHwOps tc6393xb_gfx_ops = {
+    .gfx_update  = tc6393xb_update_display,
+};
+
 TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
 {
     TC6393xbState *s;
@@ -583,10 +587,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
     memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
     s->scr_width = 480;
     s->scr_height = 640;
-    s->con = graphic_console_init(tc6393xb_update_display,
-            NULL, /* invalidate */
-            NULL, /* text_update */
-            s);
+    s->con = graphic_console_init(&tc6393xb_gfx_ops, s);
 
     return s;
 }
diff --git a/hw/tcx.c b/hw/tcx.c
index ba3857a..77c7191 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -510,6 +510,16 @@ static const MemoryRegionOps dummy_ops = {
     },
 };
 
+static const GraphicHwOps tcx_ops = {
+    .invalidate = tcx_invalidate_display,
+    .gfx_update = tcx_update_display,
+};
+
+static const GraphicHwOps tcx24_ops = {
+    .invalidate = tcx24_invalidate_display,
+    .gfx_update = tcx24_update_display,
+};
+
 static int tcx_init1(SysBusDevice *dev)
 {
     TCXState *s = FROM_SYSBUS(TCXState, dev);
@@ -562,18 +572,14 @@ static int tcx_init1(SysBusDevice *dev)
                                  &s->vram_mem, vram_offset, size);
         sysbus_init_mmio(dev, &s->vram_cplane);
 
-        s->con = graphic_console_init(tcx24_update_display,
-                                      tcx24_invalidate_display,
-                                      NULL, s);
+        s->con = graphic_console_init(&tcx24_ops, s);
     } else {
         /* THC 8 bit (dummy) */
         memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
                               TCX_THC_NREGS_8);
         sysbus_init_mmio(dev, &s->thc8);
 
-        s->con = graphic_console_init(tcx_update_display,
-                                      tcx_invalidate_display,
-                                      NULL, s);
+        s->con = graphic_console_init(&tcx_ops, s);
     }
 
     qemu_console_resize(s->con, s->width, s->height);
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index d110363..20356b5 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -78,6 +78,8 @@ static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
     memory_region_add_subregion(get_system_memory(), 0, ram_memory);
 }
 
+static const GraphicHwOps no_ops;
+
 static void puv3_load_kernel(const char *kernel_filename)
 {
     int size;
@@ -92,7 +94,7 @@ static void puv3_load_kernel(const char *kernel_filename)
     }
 
     /* cheat curses that we have a graphic console, only under ocd console */
-    graphic_console_init(NULL, NULL, NULL, NULL);
+    graphic_console_init(&no_ops, NULL);
 }
 
 static void puv3_init(QEMUMachineInitArgs *args)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 5fb04fb..3f3af9a 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -135,9 +135,7 @@ int isa_vga_mm_init(hwaddr vram_base,
     vga_common_init(&s->vga);
     vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
 
-    s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
-                                      s->vga.text_update,
-                                      s);
+    s->vga.con = graphic_console_init(s->vga.hw_ops, s);
 
     vga_init_vbe(&s->vga, address_space);
     return 0;
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 0a1aded..a76cef2 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -62,8 +62,7 @@ static int vga_initfn(ISADevice *dev)
                                         isa_mem_base + 0x000a0000,
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
-    s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->text_update, s);
+    s->con = graphic_console_init(s->hw_ops, s);
 
     vga_init_vbe(s, isa_address_space(dev));
     /* ROM BIOS */
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index a982f2a..5ffc37b 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -150,8 +150,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
     vga_common_init(s);
     vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
 
-    s->con = graphic_console_init(s->update, s->invalidate,
-                                  s->text_update, s);
+    s->con = graphic_console_init(s->hw_ops, s);
 
     /* XXX: VGA_RAM_SIZE must be a power of two */
     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
diff --git a/hw/vga.c b/hw/vga.c
index a875faa..5c87754 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2250,6 +2250,12 @@ const VMStateDescription vmstate_vga_common = {
     }
 };
 
+static const GraphicHwOps vga_ops = {
+    .invalidate  = vga_invalidate_display,
+    .gfx_update  = vga_update_display,
+    .text_update = vga_update_text,
+};
+
 void vga_common_init(VGACommonState *s)
 {
     int i, j, v, b;
@@ -2293,9 +2299,7 @@ void vga_common_init(VGACommonState *s)
     s->get_bpp = vga_get_bpp;
     s->get_offsets = vga_get_offsets;
     s->get_resolution = vga_get_resolution;
-    s->update = vga_update_display;
-    s->invalidate = vga_invalidate_display;
-    s->text_update = vga_update_text;
+    s->hw_ops = &vga_ops;
     switch (vga_retrace_method) {
     case VGA_RETRACE_DUMB:
         s->retrace = vga_dumb_retrace;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index e4bb4a0..66f9f3c 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -152,9 +152,7 @@ typedef struct VGACommonState {
     uint32_t cursor_offset;
     unsigned int (*rgb_to_pixel)(unsigned int r,
                                  unsigned int g, unsigned b);
-    graphic_hw_update_ptr update;
-    graphic_hw_invalidate_ptr invalidate;
-    graphic_hw_text_update_ptr text_update;
+    const GraphicHwOps *hw_ops;
     bool full_update_text;
     bool full_update_gfx;
     /* hardware mouse cursor support */
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 1ecee8f..c330e96 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -913,7 +913,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
     case SVGA_REG_ENABLE:
         s->enable = !!value;
         s->invalidated = 1;
-        s->vga.invalidate(&s->vga);
+        s->vga.hw_ops->invalidate(&s->vga);
         if (s->enable && s->config) {
             vga_dirty_log_stop(&s->vga);
         } else {
@@ -1058,7 +1058,7 @@ static void vmsvga_update_display(void *opaque)
     bool dirty = false;
 
     if (!s->enable) {
-        s->vga.update(&s->vga);
+        s->vga.hw_ops->gfx_update(&s->vga);
         return;
     }
 
@@ -1112,7 +1112,7 @@ static void vmsvga_invalidate_display(void *opaque)
 {
     struct vmsvga_state_s *s = opaque;
     if (!s->enable) {
-        s->vga.invalidate(&s->vga);
+        s->vga.hw_ops->invalidate(&s->vga);
         return;
     }
 
@@ -1123,8 +1123,8 @@ static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
 {
     struct vmsvga_state_s *s = opaque;
 
-    if (s->vga.text_update) {
-        s->vga.text_update(&s->vga, chardata);
+    if (s->vga.hw_ops->text_update) {
+        s->vga.hw_ops->text_update(&s->vga, chardata);
     }
 }
 
@@ -1179,15 +1179,19 @@ static const VMStateDescription vmstate_vmware_vga = {
     }
 };
 
+static const GraphicHwOps vmsvga_ops = {
+    .invalidate  = vmsvga_invalidate_display,
+    .gfx_update  = vmsvga_update_display,
+    .text_update = vmsvga_text_update,
+};
+
 static void vmsvga_init(struct vmsvga_state_s *s,
                         MemoryRegion *address_space, MemoryRegion *io)
 {
     s->scratch_size = SVGA_SCRATCH_SIZE;
     s->scratch = g_malloc(s->scratch_size * 4);
 
-    s->vga.con = graphic_console_init(vmsvga_update_display,
-                                      vmsvga_invalidate_display,
-                                      vmsvga_text_update, s);
+    s->vga.con = graphic_console_init(&vmsvga_ops, s);
 
     s->fifo_size = SVGA_FIFO_SIZE;
     memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size);
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 0db2f84..f2af7eb 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -977,6 +977,11 @@ struct XenDevOps xen_framebuffer_ops = {
     .frontend_changed = fb_frontend_changed,
 };
 
+static const GraphicHwOps xenfb_ops = {
+    .invalidate  = xenfb_invalidate,
+    .gfx_update  = xenfb_update,
+};
+
 /*
  * FIXME/TODO: Kill this.
  * Temporary needed while DisplayState reorganization is in flight.
@@ -1004,10 +1009,7 @@ wait_more:
 
     /* vfb */
     fb = container_of(xfb, struct XenFB, c.xendev);
-    fb->c.con = graphic_console_init(xenfb_update,
-                                     xenfb_invalidate,
-                                     NULL,
-                                     fb);
+    fb->c.con = graphic_console_init(&xenfb_ops, fb);
     fb->have_console = 1;
 
     /* vkbd */
diff --git a/include/ui/console.h b/include/ui/console.h
index 50cd7b0..f3e7791 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -267,13 +267,13 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
     *dest = ch;
 }
 
-typedef void (*graphic_hw_update_ptr)(void *);
-typedef void (*graphic_hw_invalidate_ptr)(void *);
-typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
+typedef struct GraphicHwOps {
+    void (*invalidate)(void *opaque);
+    void (*gfx_update)(void *opaque);
+    void (*text_update)(void *opaque, console_ch_t *text);
+} GraphicHwOps;
 
-QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
-                                  graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(const GraphicHwOps *ops,
                                   void *opaque);
 
 void graphic_hw_update(QemuConsole *con);
diff --git a/ui/console.c b/ui/console.c
index ea8c218..49ed6ef 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -119,9 +119,7 @@ struct QemuConsole {
     DisplaySurface *surface;
 
     /* Graphic console state.  */
-    graphic_hw_update_ptr hw_update;
-    graphic_hw_invalidate_ptr hw_invalidate;
-    graphic_hw_text_update_ptr hw_text_update;
+    const GraphicHwOps *hw_ops;
     void *hw;
 
     /* Text console state */
@@ -229,8 +227,8 @@ void graphic_hw_update(QemuConsole *con)
     if (!con) {
         con = active_console;
     }
-    if (con && con->hw_update) {
-        con->hw_update(con->hw);
+    if (con && con->hw_ops->gfx_update) {
+        con->hw_ops->gfx_update(con->hw);
     }
 }
 
@@ -239,8 +237,8 @@ void graphic_hw_invalidate(QemuConsole *con)
     if (!con) {
         con = active_console;
     }
-    if (con && con->hw_invalidate) {
-        con->hw_invalidate(con->hw);
+    if (con && con->hw_ops->invalidate) {
+        con->hw_ops->invalidate(con->hw);
     }
 }
 
@@ -310,8 +308,9 @@ void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
     if (!con) {
         con = active_console;
     }
-    if (con && con->hw_text_update)
-        con->hw_text_update(con->hw, chardata);
+    if (con && con->hw_ops->text_update) {
+        con->hw_ops->text_update(con->hw, chardata);
+    }
 }
 
 static void vga_fill_rect(QemuConsole *con,
@@ -1493,9 +1492,7 @@ DisplayState *init_displaystate(void)
     return display_state;
 }
 
-QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
-                                  graphic_hw_invalidate_ptr invalidate,
-                                  graphic_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(const GraphicHwOps *hw_ops,
                                   void *opaque)
 {
     int width = 640;
@@ -1506,9 +1503,7 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
     ds = get_alloc_displaystate();
     trace_console_gfx_new();
     s = new_console(ds, GRAPHIC_CONSOLE);
-    s->hw_update = update;
-    s->hw_invalidate = invalidate;
-    s->hw_text_update = text_update;
+    s->hw_ops = hw_ops;
     s->hw = opaque;
 
     s->surface = qemu_create_displaysurface(width, height);
@@ -1542,6 +1537,11 @@ static void text_console_update_cursor(void *opaque)
                    qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
 }
 
+static const GraphicHwOps text_console_ops = {
+    .invalidate  = text_console_invalidate,
+    .text_update = text_console_update,
+};
+
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 {
     QemuConsole *s;
@@ -1573,8 +1573,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
     s->cursor_timer =
         qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
 
-    s->hw_invalidate = text_console_invalidate;
-    s->hw_text_update = text_console_update;
+    s->hw_ops = &text_console_ops;
     s->hw = s;
 
     /* Set text attribute defaults */
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 19/24] console: gui timer fixes
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (17 preceding siblings ...)
  2013-04-04  7:29   ` Gerd Hoffmann
@ 2013-04-04  7:29 ` Gerd Hoffmann
  2013-04-04  7:29   ` Gerd Hoffmann
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Make gui update rate adaption code in gui_update() actually work.
Sprinkle in a tracepoint so you can see the code at work.  Remove
the update rate adaption code in vnc and make vnc simply use the
generic bits instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |    9 ++++---
 trace-events         |    1 +
 ui/console.c         |   34 ++++++++++++++++++++----
 ui/sdl.c             |   10 +++----
 ui/vnc.c             |   71 ++++++++++++++------------------------------------
 ui/vnc.h             |    2 --
 6 files changed, 60 insertions(+), 67 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index f3e7791..3cb0018 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -21,7 +21,8 @@
 #define QEMU_CAPS_LOCK_LED   (1 << 2)
 
 /* in ms */
-#define GUI_REFRESH_INTERVAL 30
+#define GUI_REFRESH_INTERVAL_DEFAULT    30
+#define GUI_REFRESH_INTERVAL_IDLE     3000
 
 typedef void QEMUPutKBDEvent(void *opaque, int keycode);
 typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
@@ -174,8 +175,7 @@ typedef struct DisplayChangeListenerOps {
 } DisplayChangeListenerOps;
 
 struct DisplayChangeListener {
-    int idle;
-    uint64_t gui_timer_interval;
+    uint64_t update_interval;
     const DisplayChangeListenerOps *ops;
     DisplayState *ds;
 
@@ -207,12 +207,13 @@ static inline int is_buffer_shared(DisplaySurface *surface)
 
 void register_displaychangelistener(DisplayState *ds,
                                     DisplayChangeListener *dcl);
+void update_displaychangelistener(DisplayChangeListener *dcl,
+                                  uint64_t interval);
 void unregister_displaychangelistener(DisplayChangeListener *dcl);
 
 void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
 void dpy_gfx_replace_surface(QemuConsole *con,
                              DisplaySurface *surface);
-void dpy_refresh(DisplayState *s);
 void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
                   int dst_x, int dst_y, int w, int h);
 void dpy_text_cursor(QemuConsole *con, int x, int y);
diff --git a/trace-events b/trace-events
index df60a93..55a3018 100644
--- a/trace-events
+++ b/trace-events
@@ -964,6 +964,7 @@ dma_map_wait(void *dbs) "dbs=%p"
 console_gfx_new(void) ""
 console_txt_new(int w, int h) "%dx%d"
 console_select(int nr) "%d"
+console_refresh(int interval) "interval %d ms"
 displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
 displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
 displaysurface_free(void *display_surface) "surface=%p"
diff --git a/ui/console.c b/ui/console.c
index 49ed6ef..be89747 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -157,6 +157,9 @@ struct QemuConsole {
 
 struct DisplayState {
     struct QEMUTimer *gui_timer;
+    uint64_t last_update;
+    uint64_t update_interval;
+    bool refreshing;
     bool have_gfx;
     bool have_text;
 
@@ -171,22 +174,32 @@ static int nb_consoles = 0;
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
 static void dpy_gfx_switch_surface(DisplayState *ds,
                                    DisplaySurface *surface);
+static void dpy_refresh(DisplayState *s);
 
 static void gui_update(void *opaque)
 {
-    uint64_t interval = GUI_REFRESH_INTERVAL;
+    uint64_t interval = GUI_REFRESH_INTERVAL_IDLE;
+    uint64_t dcl_interval;
     DisplayState *ds = opaque;
     DisplayChangeListener *dcl;
 
+    ds->refreshing = true;
     dpy_refresh(ds);
+    ds->refreshing = false;
 
     QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->gui_timer_interval &&
-            dcl->gui_timer_interval < interval) {
-            interval = dcl->gui_timer_interval;
+        dcl_interval = dcl->update_interval ?
+            dcl->update_interval : GUI_REFRESH_INTERVAL_DEFAULT;
+        if (interval > dcl_interval) {
+            interval = dcl_interval;
         }
     }
-    qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
+    if (ds->update_interval != interval) {
+        ds->update_interval = interval;
+        trace_console_refresh(interval);
+    }
+    ds->last_update = qemu_get_clock_ms(rt_clock);
+    qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
 }
 
 static void gui_setup_refresh(DisplayState *ds)
@@ -1286,6 +1299,17 @@ void register_displaychangelistener(DisplayState *ds,
     }
 }
 
+void update_displaychangelistener(DisplayChangeListener *dcl,
+                                  uint64_t interval)
+{
+    DisplayState *ds = dcl->ds;
+
+    dcl->update_interval = interval;
+    if (!ds->refreshing && ds->update_interval > interval) {
+        qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+    }
+}
+
 void unregister_displaychangelistener(DisplayChangeListener *dcl)
 {
     DisplayState *ds = dcl->ds;
diff --git a/ui/sdl.c b/ui/sdl.c
index ede31dc..97764a6 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -751,12 +751,12 @@ static void handle_activation(SDL_Event *ev)
     if (ev->active.state & SDL_APPACTIVE) {
         if (ev->active.gain) {
             /* Back to default interval */
-            dcl->gui_timer_interval = 0;
-            dcl->idle = 0;
+            update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
         } else {
-            /* Sleeping interval */
-            dcl->gui_timer_interval = 500;
-            dcl->idle = 1;
+            /* Sleeping interval.  Not using the long default here as
+             * sdl_refresh does not only update the guest screen, but
+             * also checks for gui events. */
+            update_displaychangelistener(dcl, 500);
         }
     }
 }
diff --git a/ui/vnc.c b/ui/vnc.c
index bc787cc..75ad67f 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -34,9 +34,9 @@
 #include "qmp-commands.h"
 #include "qemu/osdep.h"
 
-#define VNC_REFRESH_INTERVAL_BASE 30
+#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
 #define VNC_REFRESH_INTERVAL_INC  50
-#define VNC_REFRESH_INTERVAL_MAX  2000
+#define VNC_REFRESH_INTERVAL_MAX  GUI_REFRESH_INTERVAL_IDLE
 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
 
@@ -419,14 +419,12 @@ out_error:
 static int vnc_update_client(VncState *vs, int has_dirty);
 static int vnc_update_client_sync(VncState *vs, int has_dirty);
 static void vnc_disconnect_start(VncState *vs);
-static void vnc_init_timer(VncDisplay *vd);
-static void vnc_remove_timer(VncDisplay *vd);
 
 static void vnc_colordepth(VncState *vs);
 static void framebuffer_update_request(VncState *vs, int incremental,
                                        int x_position, int y_position,
                                        int w, int h);
-static void vnc_refresh(void *opaque);
+static void vnc_refresh(DisplayChangeListener *dcl);
 static int vnc_refresh_server_surface(VncDisplay *vd);
 
 static void vnc_dpy_update(DisplayChangeListener *dcl,
@@ -1064,11 +1062,6 @@ void vnc_disconnect_finish(VncState *vs)
         qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
     }
 
-    if (QTAILQ_EMPTY(&vs->vd->clients)) {
-        vs->vd->dcl.idle = 1;
-    }
-
-    vnc_remove_timer(vs->vd);
     if (vs->vd->lock_key_sync)
         qemu_remove_led_event_handler(vs->led);
     vnc_unlock_output(vs);
@@ -2013,9 +2006,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
     VncDisplay *vd = vs->vd;
 
     if (data[0] > 3) {
-        vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-        if (!qemu_timer_expired(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval))
-            qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
+        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
     }
 
     switch (data[0]) {
@@ -2647,18 +2638,16 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
     return has_dirty;
 }
 
-static void vnc_refresh(void *opaque)
+static void vnc_refresh(DisplayChangeListener *dcl)
 {
-    VncDisplay *vd = opaque;
+    VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
     VncState *vs, *vn;
     int has_dirty, rects = 0;
 
     graphic_hw_update(NULL);
 
     if (vnc_trylock_display(vd)) {
-        vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-        qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) +
-                       vd->timer_interval);
+        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
         return;
     }
 
@@ -2670,39 +2659,21 @@ static void vnc_refresh(void *opaque)
         /* vs might be free()ed here */
     }
 
-    /* vd->timer could be NULL now if the last client disconnected,
-     * in this case don't update the timer */
-    if (vd->timer == NULL)
+    if (QTAILQ_EMPTY(&vd->clients)) {
+        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
         return;
+    }
 
     if (has_dirty && rects) {
-        vd->timer_interval /= 2;
-        if (vd->timer_interval < VNC_REFRESH_INTERVAL_BASE)
-            vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+        vd->dcl.update_interval /= 2;
+        if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
+            vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
+        }
     } else {
-        vd->timer_interval += VNC_REFRESH_INTERVAL_INC;
-        if (vd->timer_interval > VNC_REFRESH_INTERVAL_MAX)
-            vd->timer_interval = VNC_REFRESH_INTERVAL_MAX;
-    }
-    qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
-}
-
-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);
-        graphic_hw_update(NULL);
-        vnc_refresh(vd);
-    }
-}
-
-static void vnc_remove_timer(VncDisplay *vd)
-{
-    if (vd->timer != NULL && QTAILQ_EMPTY(&vd->clients)) {
-        qemu_del_timer(vd->timer);
-        qemu_free_timer(vd->timer);
-        vd->timer = NULL;
+        vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
+        if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
+            vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
+        }
     }
 }
 
@@ -2731,7 +2702,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket)
     }
 
     VNC_DEBUG("New client on socket %d\n", csock);
-    vd->dcl.idle = 0;
+    update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
     qemu_set_nonblock(vs->csock);
 #ifdef CONFIG_VNC_WS
     if (websocket) {
@@ -2787,8 +2758,6 @@ void vnc_init_state(VncState *vs)
     vs->mouse_mode_notifier.notify = check_pointer_type_change;
     qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
 
-    vnc_init_timer(vd);
-
     /* vs might be free()ed here */
 }
 
@@ -2829,6 +2798,7 @@ static void vnc_listen_websocket_read(void *opaque)
 
 static const DisplayChangeListenerOps dcl_ops = {
     .dpy_name          = "vnc",
+    .dpy_refresh       = vnc_refresh,
     .dpy_gfx_copy      = vnc_dpy_copy,
     .dpy_gfx_update    = vnc_dpy_update,
     .dpy_gfx_switch    = vnc_dpy_switch,
@@ -2840,7 +2810,6 @@ void vnc_display_init(DisplayState *ds)
 {
     VncDisplay *vs = g_malloc0(sizeof(*vs));
 
-    vs->dcl.idle = 1;
     vnc_display = vs;
 
     vs->lsock = -1;
diff --git a/ui/vnc.h b/ui/vnc.h
index 58e002e..ad1dec2 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -142,8 +142,6 @@ struct VncDisplay
     QTAILQ_HEAD(, VncState) clients;
     int num_exclusive;
     VncSharePolicy share_policy;
-    QEMUTimer *timer;
-    int timer_interval;
     int lsock;
 #ifdef CONFIG_VNC_WS
     int lwebsock;
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
@ 2013-04-04  7:29   ` Gerd Hoffmann
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
                     ` (22 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, open list:X86, Gerd Hoffmann, Stefano Stabellini

xenfb informs the guest about the gui refresh interval so it can avoid
pointless work.  That logic was temporarely disabled for the
DisplayState reorganization.  Restore it now, with a proper interface
for it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/xenfb.c           |   47 ++++++++++++++++-------------------------------
 include/ui/console.h |    1 +
 ui/console.c         |    6 ++++++
 3 files changed, 23 insertions(+), 31 deletions(-)

diff --git a/hw/xenfb.c b/hw/xenfb.c
index f2af7eb..6344f11 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -646,7 +646,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
     dpy_gfx_update(xenfb->c.con, x, y, w, h);
 }
 
-#if 0 /* def XENFB_TYPE_REFRESH_PERIOD */
+#ifdef XENFB_TYPE_REFRESH_PERIOD
 static int xenfb_queue_full(struct XenFB *xenfb)
 {
     struct xenfb_page *page = xenfb->c.page;
@@ -705,37 +705,7 @@ static void xenfb_update(void *opaque)
         return;
 
     if (xenfb->feature_update) {
-#if 0 /* XENFB_TYPE_REFRESH_PERIOD */
-        struct DisplayChangeListener *l;
-        int period = 99999999;
-        int idle = 1;
-
-	if (xenfb_queue_full(xenfb))
-	    return;
-
-        QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
-            if (l->idle)
-                continue;
-            idle = 0;
-            if (!l->gui_timer_interval) {
-                if (period > GUI_REFRESH_INTERVAL)
-                    period = GUI_REFRESH_INTERVAL;
-            } else {
-                if (period > l->gui_timer_interval)
-                    period = l->gui_timer_interval;
-            }
-        }
-        if (idle)
-	    period = XENFB_NO_REFRESH;
-
-	if (xenfb->refresh_period != period) {
-	    xenfb_send_refresh_period(xenfb, period);
-	    xenfb->refresh_period = period;
-            xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
-	}
-#else
 	; /* nothing */
-#endif
     } else {
 	/* we don't get update notifications, thus use the
 	 * sledge hammer approach ... */
@@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
     xenfb->up_fullscreen = 0;
 }
 
+static void xenfb_update_interval(void *opaque, uint64_t interval)
+{
+    struct XenFB *xenfb = opaque;
+
+    if (xenfb->feature_update) {
+#ifdef XENFB_TYPE_REFRESH_PERIOD
+        if (xenfb_queue_full(xenfb)) {
+            return;
+        }
+        xenfb_send_refresh_period(xenfb, interval);
+#endif
+    }
+}
+
 /* QEMU display state changed, so refresh the framebuffer copy */
 static void xenfb_invalidate(void *opaque)
 {
@@ -980,6 +964,7 @@ struct XenDevOps xen_framebuffer_ops = {
 static const GraphicHwOps xenfb_ops = {
     .invalidate  = xenfb_invalidate,
     .gfx_update  = xenfb_update,
+    .update_interval = xenfb_update_interval,
 };
 
 /*
diff --git a/include/ui/console.h b/include/ui/console.h
index 3cb0018..800f458 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -272,6 +272,7 @@ typedef struct GraphicHwOps {
     void (*invalidate)(void *opaque);
     void (*gfx_update)(void *opaque);
     void (*text_update)(void *opaque, console_ch_t *text);
+    void (*update_interval)(void *opaque, uint64_t interval);
 } GraphicHwOps;
 
 QemuConsole *graphic_console_init(const GraphicHwOps *ops,
diff --git a/ui/console.c b/ui/console.c
index be89747..ead5d35 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -182,6 +182,7 @@ static void gui_update(void *opaque)
     uint64_t dcl_interval;
     DisplayState *ds = opaque;
     DisplayChangeListener *dcl;
+    int i;
 
     ds->refreshing = true;
     dpy_refresh(ds);
@@ -196,6 +197,11 @@ static void gui_update(void *opaque)
     }
     if (ds->update_interval != interval) {
         ds->update_interval = interval;
+        for (i = 0; i < nb_consoles; i++) {
+            if (consoles[i]->hw_ops->update_interval) {
+                consoles[i]->hw_ops->update_interval(consoles[i]->hw, interval);
+            }
+        }
         trace_console_refresh(interval);
     }
     ds->last_update = qemu_get_clock_ms(rt_clock);
-- 
1.7.9.7

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

* [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
@ 2013-04-04  7:29   ` Gerd Hoffmann
  0 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, open list:X86, Gerd Hoffmann, Stefano Stabellini

xenfb informs the guest about the gui refresh interval so it can avoid
pointless work.  That logic was temporarely disabled for the
DisplayState reorganization.  Restore it now, with a proper interface
for it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/xenfb.c           |   47 ++++++++++++++++-------------------------------
 include/ui/console.h |    1 +
 ui/console.c         |    6 ++++++
 3 files changed, 23 insertions(+), 31 deletions(-)

diff --git a/hw/xenfb.c b/hw/xenfb.c
index f2af7eb..6344f11 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -646,7 +646,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
     dpy_gfx_update(xenfb->c.con, x, y, w, h);
 }
 
-#if 0 /* def XENFB_TYPE_REFRESH_PERIOD */
+#ifdef XENFB_TYPE_REFRESH_PERIOD
 static int xenfb_queue_full(struct XenFB *xenfb)
 {
     struct xenfb_page *page = xenfb->c.page;
@@ -705,37 +705,7 @@ static void xenfb_update(void *opaque)
         return;
 
     if (xenfb->feature_update) {
-#if 0 /* XENFB_TYPE_REFRESH_PERIOD */
-        struct DisplayChangeListener *l;
-        int period = 99999999;
-        int idle = 1;
-
-	if (xenfb_queue_full(xenfb))
-	    return;
-
-        QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
-            if (l->idle)
-                continue;
-            idle = 0;
-            if (!l->gui_timer_interval) {
-                if (period > GUI_REFRESH_INTERVAL)
-                    period = GUI_REFRESH_INTERVAL;
-            } else {
-                if (period > l->gui_timer_interval)
-                    period = l->gui_timer_interval;
-            }
-        }
-        if (idle)
-	    period = XENFB_NO_REFRESH;
-
-	if (xenfb->refresh_period != period) {
-	    xenfb_send_refresh_period(xenfb, period);
-	    xenfb->refresh_period = period;
-            xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
-	}
-#else
 	; /* nothing */
-#endif
     } else {
 	/* we don't get update notifications, thus use the
 	 * sledge hammer approach ... */
@@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
     xenfb->up_fullscreen = 0;
 }
 
+static void xenfb_update_interval(void *opaque, uint64_t interval)
+{
+    struct XenFB *xenfb = opaque;
+
+    if (xenfb->feature_update) {
+#ifdef XENFB_TYPE_REFRESH_PERIOD
+        if (xenfb_queue_full(xenfb)) {
+            return;
+        }
+        xenfb_send_refresh_period(xenfb, interval);
+#endif
+    }
+}
+
 /* QEMU display state changed, so refresh the framebuffer copy */
 static void xenfb_invalidate(void *opaque)
 {
@@ -980,6 +964,7 @@ struct XenDevOps xen_framebuffer_ops = {
 static const GraphicHwOps xenfb_ops = {
     .invalidate  = xenfb_invalidate,
     .gfx_update  = xenfb_update,
+    .update_interval = xenfb_update_interval,
 };
 
 /*
diff --git a/include/ui/console.h b/include/ui/console.h
index 3cb0018..800f458 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -272,6 +272,7 @@ typedef struct GraphicHwOps {
     void (*invalidate)(void *opaque);
     void (*gfx_update)(void *opaque);
     void (*text_update)(void *opaque, console_ch_t *text);
+    void (*update_interval)(void *opaque, uint64_t interval);
 } GraphicHwOps;
 
 QemuConsole *graphic_console_init(const GraphicHwOps *ops,
diff --git a/ui/console.c b/ui/console.c
index be89747..ead5d35 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -182,6 +182,7 @@ static void gui_update(void *opaque)
     uint64_t dcl_interval;
     DisplayState *ds = opaque;
     DisplayChangeListener *dcl;
+    int i;
 
     ds->refreshing = true;
     dpy_refresh(ds);
@@ -196,6 +197,11 @@ static void gui_update(void *opaque)
     }
     if (ds->update_interval != interval) {
         ds->update_interval = interval;
+        for (i = 0; i < nb_consoles; i++) {
+            if (consoles[i]->hw_ops->update_interval) {
+                consoles[i]->hw_ops->update_interval(consoles[i]->hw, interval);
+            }
+        }
         trace_console_refresh(interval);
     }
     ds->last_update = qemu_get_clock_ms(rt_clock);
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 21/24] console: add qemu_console_is_*
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (19 preceding siblings ...)
  2013-04-04  7:29   ` Gerd Hoffmann
@ 2013-04-04  7:29 ` Gerd Hoffmann
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 22/24] console: allow pinning displaychangelisteners to consoles Gerd Hoffmann
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |    6 +++--
 ui/console.c         |   59 ++++++++++++++++++++++++++++----------------------
 ui/curses.c          |    7 +++---
 ui/sdl.c             |   24 ++++++++++----------
 ui/vnc.c             |    6 ++---
 5 files changed, 56 insertions(+), 46 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index 800f458..bcd0139 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -282,8 +282,10 @@ void graphic_hw_update(QemuConsole *con);
 void graphic_hw_invalidate(QemuConsole *con);
 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
 
-int is_graphic_console(void);
-int is_fixedsize_console(void);
+bool qemu_console_is_visible(QemuConsole *con);
+bool qemu_console_is_graphic(QemuConsole *con);
+bool qemu_console_is_fixedsize(QemuConsole *con);
+
 void text_consoles_set_display(DisplayState *ds);
 void console_select(unsigned int index);
 void console_color_init(DisplayState *ds);
diff --git a/ui/console.c b/ui/console.c
index ead5d35..df9a9b4 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -515,7 +515,7 @@ static void update_xy(QemuConsole *s, int x, int y)
     TextCell *c;
     int y1, y2;
 
-    if (s != active_console) {
+    if (!qemu_console_is_visible(s)) {
         return;
     }
 
@@ -543,7 +543,7 @@ static void console_show_cursor(QemuConsole *s, int show)
     int y, y1;
     int x = s->x;
 
-    if (s != active_console) {
+    if (!qemu_console_is_visible(s)) {
         return;
     }
 
@@ -579,8 +579,9 @@ static void console_refresh(QemuConsole *s)
     TextCell *c;
     int x, y, y1;
 
-    if (s != active_console)
+    if (!qemu_console_is_visible(s)) {
         return;
+    }
 
     if (s->ds->have_text) {
         s->text_x[0] = 0;
@@ -611,15 +612,10 @@ static void console_refresh(QemuConsole *s)
     }
 }
 
-static void console_scroll(int ydelta)
+static void console_scroll(QemuConsole *s, int ydelta)
 {
-    QemuConsole *s;
     int i, y1;
 
-    s = active_console;
-    if (!s || (s->console_type == GRAPHIC_CONSOLE))
-        return;
-
     if (ydelta > 0) {
         for(i = 0; i < ydelta; i++) {
             if (s->y_displayed == s->y_base)
@@ -669,7 +665,7 @@ static void console_put_lf(QemuConsole *s)
             c->t_attrib = s->t_attrib_default;
             c++;
         }
-        if (s == active_console && s->y_displayed == s->y_base) {
+        if (qemu_console_is_visible(s) && s->y_displayed == s->y_base) {
             if (s->ds->have_text) {
                 s->text_x[0] = 0;
                 s->text_y[0] = 0;
@@ -1112,16 +1108,16 @@ void kbd_put_keysym(int keysym)
 
     switch(keysym) {
     case QEMU_KEY_CTRL_UP:
-        console_scroll(-1);
+        console_scroll(s, -1);
         break;
     case QEMU_KEY_CTRL_DOWN:
-        console_scroll(1);
+        console_scroll(s, 1);
         break;
     case QEMU_KEY_CTRL_PAGEUP:
-        console_scroll(-10);
+        console_scroll(s, -10);
         break;
     case QEMU_KEY_CTRL_PAGEDOWN:
-        console_scroll(10);
+        console_scroll(s, 10);
         break;
     default:
         /* convert the QEMU keysym to VT100 key string */
@@ -1338,7 +1334,7 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
     w = MIN(w, width - x);
     h = MIN(h, height - y);
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1367,7 +1363,7 @@ void dpy_gfx_replace_surface(QemuConsole *con,
     DisplaySurface *old_surface = con->surface;
 
     con->surface = surface;
-    if (con == active_console) {
+    if (qemu_console_is_visible(con)) {
         dpy_gfx_switch_surface(s, surface);
     }
     qemu_free_displaysurface(old_surface);
@@ -1389,7 +1385,7 @@ void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
     DisplayState *s = con->ds;
     struct DisplayChangeListener *dcl;
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1406,7 +1402,7 @@ void dpy_text_cursor(QemuConsole *con, int x, int y)
     DisplayState *s = con->ds;
     struct DisplayChangeListener *dcl;
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1421,7 +1417,7 @@ void dpy_text_update(QemuConsole *con, int x, int y, int w, int h)
     DisplayState *s = con->ds;
     struct DisplayChangeListener *dcl;
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1436,7 +1432,7 @@ void dpy_text_resize(QemuConsole *con, int w, int h)
     DisplayState *s = con->ds;
     struct DisplayChangeListener *dcl;
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1451,7 +1447,7 @@ void dpy_mouse_set(QemuConsole *con, int x, int y, int on)
     DisplayState *s = con->ds;
     struct DisplayChangeListener *dcl;
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1466,7 +1462,7 @@ void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor)
     DisplayState *s = con->ds;
     struct DisplayChangeListener *dcl;
 
-    if (con != active_console) {
+    if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -1540,14 +1536,25 @@ QemuConsole *graphic_console_init(const GraphicHwOps *hw_ops,
     return s;
 }
 
-int is_graphic_console(void)
+bool qemu_console_is_visible(QemuConsole *con)
 {
-    return active_console && active_console->console_type == GRAPHIC_CONSOLE;
+    return con == active_console;
 }
 
-int is_fixedsize_console(void)
+bool qemu_console_is_graphic(QemuConsole *con)
 {
-    return active_console && active_console->console_type != TEXT_CONSOLE;
+    if (con == NULL) {
+        con = active_console;
+    }
+    return con && (con->console_type == GRAPHIC_CONSOLE);
+}
+
+bool qemu_console_is_fixedsize(QemuConsole *con)
+{
+    if (con == NULL) {
+        con = active_console;
+    }
+    return con && (con->console_type != TEXT_CONSOLE);
 }
 
 static void text_console_set_echo(CharDriverState *chr, bool echo)
diff --git a/ui/curses.c b/ui/curses.c
index ed9e65c..a85a7da 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -56,7 +56,7 @@ static void curses_update(DisplayChangeListener *dcl,
 
 static void curses_calc_pad(void)
 {
-    if (is_fixedsize_console()) {
+    if (qemu_console_is_fixedsize(NULL)) {
         width = gwidth;
         height = gheight;
     } else {
@@ -143,8 +143,9 @@ static void curses_cursor_position(DisplayChangeListener *dcl,
             curs_set(1);
             /* it seems that curs_set(1) must always be called before
              * curs_set(2) for the latter to have effect */
-            if (!is_graphic_console())
+            if (!qemu_console_is_graphic(NULL)) {
                 curs_set(2);
+            }
             return;
         }
     }
@@ -252,7 +253,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
         if (keycode == -1)
             continue;
 
-        if (is_graphic_console()) {
+        if (qemu_console_is_graphic(NULL)) {
             /* since terminals don't know about key press and release
              * events, we need to emit both for each key received */
             if (keycode & SHIFT)
diff --git a/ui/sdl.c b/ui/sdl.c
index 97764a6..c9f2928 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -358,7 +358,7 @@ static void sdl_show_cursor(void)
     if (!cursor_hide)
         return;
 
-    if (!kbd_mouse_is_absolute() || !is_graphic_console()) {
+    if (!kbd_mouse_is_absolute() || !qemu_console_is_graphic(NULL)) {
         SDL_ShowCursor(1);
         if (guest_cursor &&
                 (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
@@ -413,7 +413,7 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
     if (kbd_mouse_is_absolute()) {
         if (!absolute_enabled) {
             absolute_enabled = 1;
-            if (is_graphic_console()) {
+            if (qemu_console_is_graphic(NULL)) {
                 absolute_mouse_grab();
             }
         }
@@ -488,7 +488,7 @@ static void toggle_full_screen(void)
         } else {
             do_sdl_resize(width, height, 0);
         }
-        if (!gui_saved_grab || !is_graphic_console()) {
+        if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) {
             sdl_grab_end();
         }
     }
@@ -535,7 +535,7 @@ static void handle_keydown(SDL_Event *ev)
             if (gui_fullscreen) {
                 break;
             }
-            if (!is_graphic_console()) {
+            if (!qemu_console_is_graphic(NULL)) {
                 /* release grab if going to a text console */
                 if (gui_grab) {
                     sdl_grab_end();
@@ -563,7 +563,7 @@ static void handle_keydown(SDL_Event *ev)
         default:
             break;
         }
-    } else if (!is_graphic_console()) {
+    } else if (!qemu_console_is_graphic(NULL)) {
         int keysym = 0;
 
         if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
@@ -637,7 +637,7 @@ static void handle_keydown(SDL_Event *ev)
             kbd_put_keysym(ev->key.keysym.unicode);
         }
     }
-    if (is_graphic_console() && !gui_keysym) {
+    if (qemu_console_is_graphic(NULL) && !gui_keysym) {
         sdl_process_key(&ev->key);
     }
 }
@@ -656,7 +656,7 @@ static void handle_keyup(SDL_Event *ev)
         if (gui_keysym == 0) {
             /* exit/enter grab if pressing Ctrl-Alt */
             if (!gui_grab) {
-                if (is_graphic_console()) {
+                if (qemu_console_is_graphic(NULL)) {
                     sdl_grab_start();
                 }
             } else if (!gui_fullscreen) {
@@ -669,7 +669,7 @@ static void handle_keyup(SDL_Event *ev)
         }
         gui_keysym = 0;
     }
-    if (is_graphic_console() && !gui_keysym) {
+    if (qemu_console_is_graphic(NULL) && !gui_keysym) {
         sdl_process_key(&ev->key);
     }
 }
@@ -678,7 +678,7 @@ static void handle_mousemotion(SDL_Event *ev)
 {
     int max_x, max_y;
 
-    if (is_graphic_console() &&
+    if (qemu_console_is_graphic(NULL) &&
         (kbd_mouse_is_absolute() || absolute_enabled)) {
         max_x = real_screen->w - 1;
         max_y = real_screen->h - 1;
@@ -704,7 +704,7 @@ static void handle_mousebutton(SDL_Event *ev)
     SDL_MouseButtonEvent *bev;
     int dz;
 
-    if (!is_graphic_console()) {
+    if (!qemu_console_is_graphic(NULL)) {
         return;
     }
 
@@ -744,7 +744,7 @@ static void handle_activation(SDL_Event *ev)
         sdl_grab_end();
     }
 #endif
-    if (!gui_grab && ev->active.gain && is_graphic_console() &&
+    if (!gui_grab && ev->active.gain && qemu_console_is_graphic(NULL) &&
         (kbd_mouse_is_absolute() || absolute_enabled)) {
         absolute_mouse_grab();
     }
@@ -771,7 +771,7 @@ static void sdl_refresh(DisplayChangeListener *dcl)
     }
 
     graphic_hw_update(NULL);
-    SDL_EnableUNICODE(!is_graphic_console());
+    SDL_EnableUNICODE(!qemu_console_is_graphic(NULL));
 
     while (SDL_PollEvent(ev)) {
         switch (ev->type) {
diff --git a/ui/vnc.c b/ui/vnc.c
index 75ad67f..8ee66b7 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1609,7 +1609,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
         }
     }
 
-    if (is_graphic_console()) {
+    if (qemu_console_is_graphic(NULL)) {
         if (keycode & SCANCODE_GREY)
             kbd_put_keycode(SCANCODE_EMUL0);
         if (down)
@@ -1728,7 +1728,7 @@ static void vnc_release_modifiers(VncState *vs)
     };
     int i, keycode;
 
-    if (!is_graphic_console()) {
+    if (!qemu_console_is_graphic(NULL)) {
         return;
     }
     for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
@@ -1748,7 +1748,7 @@ static void key_event(VncState *vs, int down, uint32_t sym)
     int keycode;
     int lsym = sym;
 
-    if (lsym >= 'A' && lsym <= 'Z' && is_graphic_console()) {
+    if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
         lsym = lsym - 'A' + 'a';
     }
 
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 22/24] console: allow pinning displaychangelisteners to consoles
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (20 preceding siblings ...)
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 21/24] console: add qemu_console_is_* Gerd Hoffmann
@ 2013-04-04  7:29 ` Gerd Hoffmann
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 23/24] gtk: custom cursor support Gerd Hoffmann
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 24/24] qxl: register QemuConsole for secondary cards Gerd Hoffmann
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

DisplayChangeListener gets a new QemuConsole field, which can be set to
non-NULL before registering.  This will pin the QemuConsole, so that
particular DisplayChangeListener will not follow console switches.

spice+gtk (which don't support text console input anyway) are switched
over to be pinned to console 0, which usually is the graphical display.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c                   |    2 +-
 include/ui/console.h       |    2 +
 include/ui/spice-display.h |    1 -
 ui/console.c               |  103 +++++++++++++++++++++++++++++++-------------
 ui/gtk.c                   |    3 +-
 ui/spice-display.c         |   11 ++---
 6 files changed, 84 insertions(+), 38 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 36f18fd..320c017 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -2061,7 +2061,6 @@ static int qxl_init_primary(PCIDevice *dev)
     portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
 
     vga->con = graphic_console_init(&qxl_ops, qxl);
-    qxl->ssd.con = vga->con,
     qemu_spice_display_init_common(&qxl->ssd);
 
     rc = qxl_init_common(qxl);
@@ -2070,6 +2069,7 @@ static int qxl_init_primary(PCIDevice *dev)
     }
 
     qxl->ssd.dcl.ops = &display_listener_ops;
+    qxl->ssd.dcl.con = vga->con;
     ds = qemu_console_displaystate(vga->con);
     register_displaychangelistener(ds, &qxl->ssd.dcl);
     return rc;
diff --git a/include/ui/console.h b/include/ui/console.h
index bcd0139..e591d74 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -178,6 +178,7 @@ struct DisplayChangeListener {
     uint64_t update_interval;
     const DisplayChangeListenerOps *ops;
     DisplayState *ds;
+    QemuConsole *con;
 
     QLIST_ENTRY(DisplayChangeListener) next;
 };
@@ -282,6 +283,7 @@ void graphic_hw_update(QemuConsole *con);
 void graphic_hw_invalidate(QemuConsole *con);
 void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
 
+QemuConsole *qemu_console_lookup_by_index(unsigned int index);
 bool qemu_console_is_visible(QemuConsole *con);
 bool qemu_console_is_graphic(QemuConsole *con);
 bool qemu_console_is_fixedsize(QemuConsole *con);
diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h
index 7a20fc4..a46bc80 100644
--- a/include/ui/spice-display.h
+++ b/include/ui/spice-display.h
@@ -71,7 +71,6 @@ typedef struct SimpleSpiceDisplay SimpleSpiceDisplay;
 typedef struct SimpleSpiceUpdate SimpleSpiceUpdate;
 
 struct SimpleSpiceDisplay {
-    QemuConsole *con;
     DisplaySurface *ds;
     DisplayChangeListener dcl;
     void *buf;
diff --git a/ui/console.c b/ui/console.c
index df9a9b4..cf7c0eb 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -117,6 +117,7 @@ struct QemuConsole {
     console_type_t console_type;
     DisplayState *ds;
     DisplaySurface *surface;
+    int dcls;
 
     /* Graphic console state.  */
     const GraphicHwOps *hw_ops;
@@ -172,8 +173,6 @@ static QemuConsole *consoles[MAX_CONSOLES];
 static int nb_consoles = 0;
 
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
-static void dpy_gfx_switch_surface(DisplayState *ds,
-                                   DisplaySurface *surface);
 static void dpy_refresh(DisplayState *s);
 
 static void gui_update(void *opaque)
@@ -309,7 +308,7 @@ write_err:
 
 void qmp_screendump(const char *filename, Error **errp)
 {
-    QemuConsole *con = consoles[0];
+    QemuConsole *con = qemu_console_lookup_by_index(0);
     DisplaySurface *surface;
 
     if (con == NULL) {
@@ -1022,13 +1021,14 @@ static void console_putchar(QemuConsole *s, int ch)
 
 void console_select(unsigned int index)
 {
+    DisplayChangeListener *dcl;
     QemuConsole *s;
 
     if (index >= MAX_CONSOLES)
         return;
 
     trace_console_select(index);
-    s = consoles[index];
+    s = qemu_console_lookup_by_index(index);
     if (s) {
         DisplayState *ds = s->ds;
 
@@ -1037,7 +1037,14 @@ void console_select(unsigned int index)
         }
         active_console = s;
         if (ds->have_gfx) {
-            dpy_gfx_switch_surface(ds, s->surface);
+            QLIST_FOREACH(dcl, &ds->listeners, next) {
+                if (dcl->con != NULL) {
+                    continue;
+                }
+                if (dcl->ops->dpy_gfx_switch) {
+                    dcl->ops->dpy_gfx_switch(dcl, s->surface);
+                }
+            }
             dpy_gfx_update(s, 0, 0, surface_width(s->surface),
                            surface_height(s->surface));
         }
@@ -1292,12 +1299,20 @@ void qemu_free_displaysurface(DisplaySurface *surface)
 void register_displaychangelistener(DisplayState *ds,
                                     DisplayChangeListener *dcl)
 {
+    QemuConsole *con;
+
     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_switch && active_console) {
-        dcl->ops->dpy_gfx_switch(dcl, active_console->surface);
+    if (dcl->con) {
+        dcl->con->dcls++;
+        con = dcl->con;
+    } else {
+        con = active_console;
+    }
+    if (dcl->ops->dpy_gfx_switch && con) {
+        dcl->ops->dpy_gfx_switch(dcl, con->surface);
     }
 }
 
@@ -1316,6 +1331,9 @@ void unregister_displaychangelistener(DisplayChangeListener *dcl)
 {
     DisplayState *ds = dcl->ds;
     trace_displaychangelistener_unregister(dcl, dcl->ops->dpy_name);
+    if (dcl->con) {
+        dcl->con->dcls--;
+    }
     QLIST_REMOVE(dcl, next);
     gui_setup_refresh(ds);
 }
@@ -1323,7 +1341,7 @@ void unregister_displaychangelistener(DisplayChangeListener *dcl)
 void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
     int width = surface_width(con->surface);
     int height = surface_height(con->surface);
 
@@ -1338,40 +1356,38 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_gfx_update) {
             dcl->ops->dpy_gfx_update(dcl, x, y, w, h);
         }
     }
 }
 
-static void dpy_gfx_switch_surface(DisplayState *ds,
-                                   DisplaySurface *surface)
-{
-    struct DisplayChangeListener *dcl;
-
-    QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->ops->dpy_gfx_switch) {
-            dcl->ops->dpy_gfx_switch(dcl, surface);
-        }
-    }
-}
-
 void dpy_gfx_replace_surface(QemuConsole *con,
                              DisplaySurface *surface)
 {
     DisplayState *s = con->ds;
     DisplaySurface *old_surface = con->surface;
+    DisplayChangeListener *dcl;
 
     con->surface = surface;
-    if (qemu_console_is_visible(con)) {
-        dpy_gfx_switch_surface(s, surface);
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
+        if (dcl->ops->dpy_gfx_switch) {
+            dcl->ops->dpy_gfx_switch(dcl, surface);
+        }
     }
     qemu_free_displaysurface(old_surface);
 }
 
 void dpy_refresh(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
+
     QLIST_FOREACH(dcl, &s->listeners, next) {
         if (dcl->ops->dpy_refresh) {
             dcl->ops->dpy_refresh(dcl);
@@ -1383,12 +1399,15 @@ void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
                   int dst_x, int dst_y, int w, int h)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
 
     if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_gfx_copy) {
             dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h);
         } else { /* TODO */
@@ -1400,12 +1419,15 @@ void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
 void dpy_text_cursor(QemuConsole *con, int x, int y)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
 
     if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_text_cursor) {
             dcl->ops->dpy_text_cursor(dcl, x, y);
         }
@@ -1415,12 +1437,15 @@ void dpy_text_cursor(QemuConsole *con, int x, int y)
 void dpy_text_update(QemuConsole *con, int x, int y, int w, int h)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
 
     if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_text_update) {
             dcl->ops->dpy_text_update(dcl, x, y, w, h);
         }
@@ -1436,6 +1461,9 @@ void dpy_text_resize(QemuConsole *con, int w, int h)
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_text_resize) {
             dcl->ops->dpy_text_resize(dcl, w, h);
         }
@@ -1445,12 +1473,15 @@ void dpy_text_resize(QemuConsole *con, int w, int h)
 void dpy_mouse_set(QemuConsole *con, int x, int y, int on)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
 
     if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_mouse_set) {
             dcl->ops->dpy_mouse_set(dcl, x, y, on);
         }
@@ -1460,12 +1491,15 @@ void dpy_mouse_set(QemuConsole *con, int x, int y, int on)
 void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
 
     if (!qemu_console_is_visible(con)) {
         return;
     }
     QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (con != (dcl->con ? dcl->con : active_console)) {
+            continue;
+        }
         if (dcl->ops->dpy_cursor_define) {
             dcl->ops->dpy_cursor_define(dcl, cursor);
         }
@@ -1475,7 +1509,8 @@ void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor)
 bool dpy_cursor_define_supported(QemuConsole *con)
 {
     DisplayState *s = con->ds;
-    struct DisplayChangeListener *dcl;
+    DisplayChangeListener *dcl;
+
     QLIST_FOREACH(dcl, &s->listeners, next) {
         if (dcl->ops->dpy_cursor_define) {
             return true;
@@ -1536,9 +1571,17 @@ QemuConsole *graphic_console_init(const GraphicHwOps *hw_ops,
     return s;
 }
 
+QemuConsole *qemu_console_lookup_by_index(unsigned int index)
+{
+    if (index >= MAX_CONSOLES) {
+        return NULL;
+    }
+    return consoles[index];
+}
+
 bool qemu_console_is_visible(QemuConsole *con)
 {
-    return con == active_console;
+    return (con == active_console) || (con->dcls > 0);
 }
 
 bool qemu_console_is_graphic(QemuConsole *con)
diff --git a/ui/gtk.c b/ui/gtk.c
index ef2665a..3c23ce7 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -327,7 +327,7 @@ static void gd_update(DisplayChangeListener *dcl,
 
 static void gd_refresh(DisplayChangeListener *dcl)
 {
-    graphic_hw_update(NULL);
+    graphic_hw_update(dcl->con);
 }
 
 static void gd_switch(DisplayChangeListener *dcl,
@@ -1368,6 +1368,7 @@ void gtk_display_init(DisplayState *ds)
     gtk_init(NULL, NULL);
 
     s->dcl.ops = &dcl_ops;
+    s->dcl.con = qemu_console_lookup_by_index(0);
 
     s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 #if GTK_CHECK_VERSION(3, 2, 0)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 2c01674..53c19be 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -398,14 +398,14 @@ void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
 void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 {
     if (ssd->cursor) {
-        assert(ssd->con);
-        dpy_cursor_define(ssd->con, ssd->cursor);
+        assert(ssd->dcl.con);
+        dpy_cursor_define(ssd->dcl.con, ssd->cursor);
         cursor_put(ssd->cursor);
         ssd->cursor = NULL;
     }
     if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
-        assert(ssd->con);
-        dpy_mouse_set(ssd->con, ssd->mouse_x, ssd->mouse_y, 1);
+        assert(ssd->dcl.con);
+        dpy_mouse_set(ssd->dcl.con, ssd->mouse_x, ssd->mouse_y, 1);
         ssd->mouse_x = -1;
         ssd->mouse_y = -1;
     }
@@ -414,7 +414,7 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
 {
     dprint(3, "%s:\n", __func__);
-    graphic_hw_update(ssd->con);
+    graphic_hw_update(ssd->dcl.con);
 
     qemu_mutex_lock(&ssd->lock);
     if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) {
@@ -624,6 +624,7 @@ void qemu_spice_display_init(DisplayState *ds)
     qemu_spice_create_host_memslot(ssd);
 
     ssd->dcl.ops = &display_listener_ops;
+    ssd->dcl.con = qemu_console_lookup_by_index(0);
     register_displaychangelistener(ds, &ssd->dcl);
 
     qemu_spice_create_host_primary(ssd);
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 23/24] gtk: custom cursor support
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (21 preceding siblings ...)
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 22/24] console: allow pinning displaychangelisteners to consoles Gerd Hoffmann
@ 2013-04-04  7:29 ` Gerd Hoffmann
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 24/24] qxl: register QemuConsole for secondary cards Gerd Hoffmann
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Makes gtk ui play nicely with qxl (and vmware_svga)
as you can actually see your pointer now ;)

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/gtk.c |   33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/ui/gtk.c b/ui/gtk.c
index 3c23ce7..927b88a 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -330,6 +330,37 @@ static void gd_refresh(DisplayChangeListener *dcl)
     graphic_hw_update(dcl->con);
 }
 
+static void gd_mouse_set(DisplayChangeListener *dcl,
+                         int x, int y, int visible)
+{
+    GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
+    gint x_root, y_root;
+
+    gdk_window_get_root_coords(s->drawing_area->window,
+                               x, y, &x_root, &y_root);
+    gdk_display_warp_pointer(gtk_widget_get_display(s->drawing_area),
+                             gtk_widget_get_screen(s->drawing_area),
+                             x_root, y_root);
+}
+
+static void gd_cursor_define(DisplayChangeListener *dcl,
+                             QEMUCursor *c)
+{
+    GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
+    GdkPixbuf *pixbuf;
+    GdkCursor *cursor;
+
+    pixbuf = gdk_pixbuf_new_from_data((guchar *)(c->data),
+                                      GDK_COLORSPACE_RGB, true, 8,
+                                      c->width, c->height, c->width * 4,
+                                      NULL, NULL);
+    cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(s->drawing_area),
+                                        pixbuf, c->hot_x, c->hot_y);
+    gdk_window_set_cursor(s->drawing_area->window, cursor);
+    g_object_unref(pixbuf);
+    g_object_unref(cursor);
+}
+
 static void gd_switch(DisplayChangeListener *dcl,
                       DisplaySurface *surface)
 {
@@ -1358,6 +1389,8 @@ static const DisplayChangeListenerOps dcl_ops = {
     .dpy_gfx_update    = gd_update,
     .dpy_gfx_switch    = gd_switch,
     .dpy_refresh       = gd_refresh,
+    .dpy_mouse_set     = gd_mouse_set,
+    .dpy_cursor_define = gd_cursor_define,
 };
 
 void gtk_display_init(DisplayState *ds)
-- 
1.7.9.7

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

* [Qemu-devel] [PATCH 24/24] qxl: register QemuConsole for secondary cards
  2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
                   ` (22 preceding siblings ...)
  2013-04-04  7:29 ` [Qemu-devel] [PATCH 23/24] gtk: custom cursor support Gerd Hoffmann
@ 2013-04-04  7:29 ` Gerd Hoffmann
  23 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-04  7:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Hook secondary qxl cards properly into the qemu console subsystem.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 320c017..e484610 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1769,7 +1769,10 @@ static void qxl_hw_invalidate(void *opaque)
     PCIQXLDevice *qxl = opaque;
     VGACommonState *vga = &qxl->vga;
 
-    vga->hw_ops->invalidate(vga);
+    if (qxl->mode == QXL_MODE_VGA) {
+        vga->hw_ops->invalidate(vga);
+        return;
+    }
 }
 
 static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
@@ -2085,6 +2088,7 @@ static int qxl_init_secondary(PCIDevice *dev)
     memory_region_init_ram(&qxl->vga.vram, "qxl.vgavram", qxl->vga.vram_size);
     vmstate_register_ram(&qxl->vga.vram, &qxl->pci.qdev);
     qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
+    qxl->vga.con = graphic_console_init(&qxl_ops, qxl);
 
     return qxl_init_common(qxl);
 }
-- 
1.7.9.7

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

* Re: [Qemu-devel] [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
  2013-04-04  7:29   ` Gerd Hoffmann
@ 2013-04-04 17:06     ` Stefano Stabellini
  -1 siblings, 0 replies; 36+ messages in thread
From: Stefano Stabellini @ 2013-04-04 17:06 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Anthony Liguori, open list:X86, qemu-devel, Stefano Stabellini

On Thu, 4 Apr 2013, Gerd Hoffmann wrote:
> xenfb informs the guest about the gui refresh interval so it can avoid
> pointless work.  That logic was temporarely disabled for the
> DisplayState reorganization.  Restore it now, with a proper interface
> for it.
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/xenfb.c           |   47 ++++++++++++++++-------------------------------
>  include/ui/console.h |    1 +
>  ui/console.c         |    6 ++++++
>  3 files changed, 23 insertions(+), 31 deletions(-)
> 
> diff --git a/hw/xenfb.c b/hw/xenfb.c
> index f2af7eb..6344f11 100644
> --- a/hw/xenfb.c
> +++ b/hw/xenfb.c
> @@ -646,7 +646,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
>      dpy_gfx_update(xenfb->c.con, x, y, w, h);
>  }
>  
> -#if 0 /* def XENFB_TYPE_REFRESH_PERIOD */
> +#ifdef XENFB_TYPE_REFRESH_PERIOD
>  static int xenfb_queue_full(struct XenFB *xenfb)
>  {
>      struct xenfb_page *page = xenfb->c.page;
> @@ -705,37 +705,7 @@ static void xenfb_update(void *opaque)
>          return;
>  
>      if (xenfb->feature_update) {
> -#if 0 /* XENFB_TYPE_REFRESH_PERIOD */
> -        struct DisplayChangeListener *l;
> -        int period = 99999999;
> -        int idle = 1;
> -
> -	if (xenfb_queue_full(xenfb))
> -	    return;
> -
> -        QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
> -            if (l->idle)
> -                continue;
> -            idle = 0;
> -            if (!l->gui_timer_interval) {
> -                if (period > GUI_REFRESH_INTERVAL)
> -                    period = GUI_REFRESH_INTERVAL;
> -            } else {
> -                if (period > l->gui_timer_interval)
> -                    period = l->gui_timer_interval;
> -            }
> -        }
> -        if (idle)
> -	    period = XENFB_NO_REFRESH;
> -
> -	if (xenfb->refresh_period != period) {
> -	    xenfb_send_refresh_period(xenfb, period);
> -	    xenfb->refresh_period = period;
> -            xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
> -	}
> -#else
>  	; /* nothing */
> -#endif
>      } else {
>  	/* we don't get update notifications, thus use the
>  	 * sledge hammer approach ... */

You might as well remove the if () nothing; case.


> @@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
>      xenfb->up_fullscreen = 0;
>  }
>  
> +static void xenfb_update_interval(void *opaque, uint64_t interval)
> +{
> +    struct XenFB *xenfb = opaque;
> +
> +    if (xenfb->feature_update) {
> +#ifdef XENFB_TYPE_REFRESH_PERIOD
> +        if (xenfb_queue_full(xenfb)) {
> +            return;
> +        }
> +        xenfb_send_refresh_period(xenfb, interval);

Shouldn't we be updating xenfb->refresh_period here?
And shouldn't we call xenfb_send_refresh_period only if interval !=
xenfb->refresh_period?
On the other hand if refresh_period is not useful anymore, shouldn't we
remove it from struct XenFB?



> +#endif
> +    }
> +}
> +
>  /* QEMU display state changed, so refresh the framebuffer copy */
>  static void xenfb_invalidate(void *opaque)
>  {
> @@ -980,6 +964,7 @@ struct XenDevOps xen_framebuffer_ops = {
>  static const GraphicHwOps xenfb_ops = {
>      .invalidate  = xenfb_invalidate,
>      .gfx_update  = xenfb_update,
> +    .update_interval = xenfb_update_interval,
>  };
>  
>  /*
> diff --git a/include/ui/console.h b/include/ui/console.h
> index 3cb0018..800f458 100644
> --- a/include/ui/console.h
> +++ b/include/ui/console.h
> @@ -272,6 +272,7 @@ typedef struct GraphicHwOps {
>      void (*invalidate)(void *opaque);
>      void (*gfx_update)(void *opaque);
>      void (*text_update)(void *opaque, console_ch_t *text);
> +    void (*update_interval)(void *opaque, uint64_t interval);
>  } GraphicHwOps;
>  
>  QemuConsole *graphic_console_init(const GraphicHwOps *ops,
> diff --git a/ui/console.c b/ui/console.c
> index be89747..ead5d35 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -182,6 +182,7 @@ static void gui_update(void *opaque)
>      uint64_t dcl_interval;
>      DisplayState *ds = opaque;
>      DisplayChangeListener *dcl;
> +    int i;
>  
>      ds->refreshing = true;
>      dpy_refresh(ds);
> @@ -196,6 +197,11 @@ static void gui_update(void *opaque)
>      }
>      if (ds->update_interval != interval) {
>          ds->update_interval = interval;
> +        for (i = 0; i < nb_consoles; i++) {
> +            if (consoles[i]->hw_ops->update_interval) {
> +                consoles[i]->hw_ops->update_interval(consoles[i]->hw, interval);
> +            }
> +        }
>          trace_console_refresh(interval);
>      }
>      ds->last_update = qemu_get_clock_ms(rt_clock);
> -- 
> 1.7.9.7
> 

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

* Re: [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
@ 2013-04-04 17:06     ` Stefano Stabellini
  0 siblings, 0 replies; 36+ messages in thread
From: Stefano Stabellini @ 2013-04-04 17:06 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Anthony Liguori, open list:X86, qemu-devel, Stefano Stabellini

On Thu, 4 Apr 2013, Gerd Hoffmann wrote:
> xenfb informs the guest about the gui refresh interval so it can avoid
> pointless work.  That logic was temporarely disabled for the
> DisplayState reorganization.  Restore it now, with a proper interface
> for it.
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/xenfb.c           |   47 ++++++++++++++++-------------------------------
>  include/ui/console.h |    1 +
>  ui/console.c         |    6 ++++++
>  3 files changed, 23 insertions(+), 31 deletions(-)
> 
> diff --git a/hw/xenfb.c b/hw/xenfb.c
> index f2af7eb..6344f11 100644
> --- a/hw/xenfb.c
> +++ b/hw/xenfb.c
> @@ -646,7 +646,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
>      dpy_gfx_update(xenfb->c.con, x, y, w, h);
>  }
>  
> -#if 0 /* def XENFB_TYPE_REFRESH_PERIOD */
> +#ifdef XENFB_TYPE_REFRESH_PERIOD
>  static int xenfb_queue_full(struct XenFB *xenfb)
>  {
>      struct xenfb_page *page = xenfb->c.page;
> @@ -705,37 +705,7 @@ static void xenfb_update(void *opaque)
>          return;
>  
>      if (xenfb->feature_update) {
> -#if 0 /* XENFB_TYPE_REFRESH_PERIOD */
> -        struct DisplayChangeListener *l;
> -        int period = 99999999;
> -        int idle = 1;
> -
> -	if (xenfb_queue_full(xenfb))
> -	    return;
> -
> -        QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
> -            if (l->idle)
> -                continue;
> -            idle = 0;
> -            if (!l->gui_timer_interval) {
> -                if (period > GUI_REFRESH_INTERVAL)
> -                    period = GUI_REFRESH_INTERVAL;
> -            } else {
> -                if (period > l->gui_timer_interval)
> -                    period = l->gui_timer_interval;
> -            }
> -        }
> -        if (idle)
> -	    period = XENFB_NO_REFRESH;
> -
> -	if (xenfb->refresh_period != period) {
> -	    xenfb_send_refresh_period(xenfb, period);
> -	    xenfb->refresh_period = period;
> -            xen_be_printf(&xenfb->c.xendev, 1, "refresh period: %d\n", period);
> -	}
> -#else
>  	; /* nothing */
> -#endif
>      } else {
>  	/* we don't get update notifications, thus use the
>  	 * sledge hammer approach ... */

You might as well remove the if () nothing; case.


> @@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
>      xenfb->up_fullscreen = 0;
>  }
>  
> +static void xenfb_update_interval(void *opaque, uint64_t interval)
> +{
> +    struct XenFB *xenfb = opaque;
> +
> +    if (xenfb->feature_update) {
> +#ifdef XENFB_TYPE_REFRESH_PERIOD
> +        if (xenfb_queue_full(xenfb)) {
> +            return;
> +        }
> +        xenfb_send_refresh_period(xenfb, interval);

Shouldn't we be updating xenfb->refresh_period here?
And shouldn't we call xenfb_send_refresh_period only if interval !=
xenfb->refresh_period?
On the other hand if refresh_period is not useful anymore, shouldn't we
remove it from struct XenFB?



> +#endif
> +    }
> +}
> +
>  /* QEMU display state changed, so refresh the framebuffer copy */
>  static void xenfb_invalidate(void *opaque)
>  {
> @@ -980,6 +964,7 @@ struct XenDevOps xen_framebuffer_ops = {
>  static const GraphicHwOps xenfb_ops = {
>      .invalidate  = xenfb_invalidate,
>      .gfx_update  = xenfb_update,
> +    .update_interval = xenfb_update_interval,
>  };
>  
>  /*
> diff --git a/include/ui/console.h b/include/ui/console.h
> index 3cb0018..800f458 100644
> --- a/include/ui/console.h
> +++ b/include/ui/console.h
> @@ -272,6 +272,7 @@ typedef struct GraphicHwOps {
>      void (*invalidate)(void *opaque);
>      void (*gfx_update)(void *opaque);
>      void (*text_update)(void *opaque, console_ch_t *text);
> +    void (*update_interval)(void *opaque, uint64_t interval);
>  } GraphicHwOps;
>  
>  QemuConsole *graphic_console_init(const GraphicHwOps *ops,
> diff --git a/ui/console.c b/ui/console.c
> index be89747..ead5d35 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -182,6 +182,7 @@ static void gui_update(void *opaque)
>      uint64_t dcl_interval;
>      DisplayState *ds = opaque;
>      DisplayChangeListener *dcl;
> +    int i;
>  
>      ds->refreshing = true;
>      dpy_refresh(ds);
> @@ -196,6 +197,11 @@ static void gui_update(void *opaque)
>      }
>      if (ds->update_interval != interval) {
>          ds->update_interval = interval;
> +        for (i = 0; i < nb_consoles; i++) {
> +            if (consoles[i]->hw_ops->update_interval) {
> +                consoles[i]->hw_ops->update_interval(consoles[i]->hw, interval);
> +            }
> +        }
>          trace_console_refresh(interval);
>      }
>      ds->last_update = qemu_get_clock_ms(rt_clock);
> -- 
> 1.7.9.7
> 

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

* Re: [Qemu-devel] [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
  2013-04-04 17:06     ` Stefano Stabellini
@ 2013-04-05  7:28       ` Gerd Hoffmann
  -1 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-05  7:28 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Anthony Liguori, X86, qemu-devel

>> -#else
>>  	; /* nothing */
>> -#endif
>>      } else {
>>  	/* we don't get update notifications, thus use the
>>  	 * sledge hammer approach ... */
> 
> You might as well remove the if () nothing; case.

Yep, will do.

>> @@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
>>      xenfb->up_fullscreen = 0;
>>  }
>>  
>> +static void xenfb_update_interval(void *opaque, uint64_t interval)
>> +{
>> +    struct XenFB *xenfb = opaque;
>> +
>> +    if (xenfb->feature_update) {
>> +#ifdef XENFB_TYPE_REFRESH_PERIOD
>> +        if (xenfb_queue_full(xenfb)) {
>> +            return;
>> +        }
>> +        xenfb_send_refresh_period(xenfb, interval);
> 
> Shouldn't we be updating xenfb->refresh_period here? And shouldn't we
> call xenfb_send_refresh_period only if interval != 
> xenfb->refresh_period?

> On the other hand if refresh_period is not useful anymore, shouldn't
> we remove it from struct XenFB?

xenfb_update_interval is only called when interval changes, which I
think means we don't need refresh_period any more, correct?

cheers,
  Gerd

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

* Re: [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
@ 2013-04-05  7:28       ` Gerd Hoffmann
  0 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-05  7:28 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Anthony Liguori, X86, qemu-devel

>> -#else
>>  	; /* nothing */
>> -#endif
>>      } else {
>>  	/* we don't get update notifications, thus use the
>>  	 * sledge hammer approach ... */
> 
> You might as well remove the if () nothing; case.

Yep, will do.

>> @@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
>>      xenfb->up_fullscreen = 0;
>>  }
>>  
>> +static void xenfb_update_interval(void *opaque, uint64_t interval)
>> +{
>> +    struct XenFB *xenfb = opaque;
>> +
>> +    if (xenfb->feature_update) {
>> +#ifdef XENFB_TYPE_REFRESH_PERIOD
>> +        if (xenfb_queue_full(xenfb)) {
>> +            return;
>> +        }
>> +        xenfb_send_refresh_period(xenfb, interval);
> 
> Shouldn't we be updating xenfb->refresh_period here? And shouldn't we
> call xenfb_send_refresh_period only if interval != 
> xenfb->refresh_period?

> On the other hand if refresh_period is not useful anymore, shouldn't
> we remove it from struct XenFB?

xenfb_update_interval is only called when interval changes, which I
think means we don't need refresh_period any more, correct?

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
  2013-04-05  7:28       ` Gerd Hoffmann
@ 2013-04-05 10:07         ` Stefano Stabellini
  -1 siblings, 0 replies; 36+ messages in thread
From: Stefano Stabellini @ 2013-04-05 10:07 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, X86, qemu-devel, Stefano Stabellini

On Fri, 5 Apr 2013, Gerd Hoffmann wrote:
> >> -#else
> >>  	; /* nothing */
> >> -#endif
> >>      } else {
> >>  	/* we don't get update notifications, thus use the
> >>  	 * sledge hammer approach ... */
> > 
> > You might as well remove the if () nothing; case.
> 
> Yep, will do.
> 
> >> @@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
> >>      xenfb->up_fullscreen = 0;
> >>  }
> >>  
> >> +static void xenfb_update_interval(void *opaque, uint64_t interval)
> >> +{
> >> +    struct XenFB *xenfb = opaque;
> >> +
> >> +    if (xenfb->feature_update) {
> >> +#ifdef XENFB_TYPE_REFRESH_PERIOD
> >> +        if (xenfb_queue_full(xenfb)) {
> >> +            return;
> >> +        }
> >> +        xenfb_send_refresh_period(xenfb, interval);
> > 
> > Shouldn't we be updating xenfb->refresh_period here? And shouldn't we
> > call xenfb_send_refresh_period only if interval != 
> > xenfb->refresh_period?
> 
> > On the other hand if refresh_period is not useful anymore, shouldn't
> > we remove it from struct XenFB?
> 
> xenfb_update_interval is only called when interval changes, which I
> think means we don't need refresh_period any more, correct?
 
that's right

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

* Re: [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb
@ 2013-04-05 10:07         ` Stefano Stabellini
  0 siblings, 0 replies; 36+ messages in thread
From: Stefano Stabellini @ 2013-04-05 10:07 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, X86, qemu-devel, Stefano Stabellini

On Fri, 5 Apr 2013, Gerd Hoffmann wrote:
> >> -#else
> >>  	; /* nothing */
> >> -#endif
> >>      } else {
> >>  	/* we don't get update notifications, thus use the
> >>  	 * sledge hammer approach ... */
> > 
> > You might as well remove the if () nothing; case.
> 
> Yep, will do.
> 
> >> @@ -785,6 +755,20 @@ static void xenfb_update(void *opaque)
> >>      xenfb->up_fullscreen = 0;
> >>  }
> >>  
> >> +static void xenfb_update_interval(void *opaque, uint64_t interval)
> >> +{
> >> +    struct XenFB *xenfb = opaque;
> >> +
> >> +    if (xenfb->feature_update) {
> >> +#ifdef XENFB_TYPE_REFRESH_PERIOD
> >> +        if (xenfb_queue_full(xenfb)) {
> >> +            return;
> >> +        }
> >> +        xenfb_send_refresh_period(xenfb, interval);
> > 
> > Shouldn't we be updating xenfb->refresh_period here? And shouldn't we
> > call xenfb_send_refresh_period only if interval != 
> > xenfb->refresh_period?
> 
> > On the other hand if refresh_period is not useful anymore, shouldn't
> > we remove it from struct XenFB?
> 
> xenfb_update_interval is only called when interval changes, which I
> think means we don't need refresh_period any more, correct?
 
that's right

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

* Re: [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen resize bug introduced after console revamp
  2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
@ 2013-04-05 11:21   ` Alexandru Damian
  0 siblings, 0 replies; 36+ messages in thread
From: Alexandru Damian @ 2013-04-05 11:21 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel


+1, verified to work with both 16-bit and 32-bit depth consoles.

Alex

On Thu, Apr 04, 2013 at 09:28:44AM +0200, Gerd Hoffmann wrote:
> From: Igor Mitsyanko <i.mitsyanko@gmail.com>
> 
> In vmsvga display update function, a pointer to DisplaySurface must be acquired
> after a call to vmsvga_check_size since this function might replace current
> DisplaySurface with a new one.
> 
> Signed-off-by: Igor Mitsyanko <i.mitsyanko@gmail.com>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hw/vmware_vga.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
> index 5b9ce8f..c0aac31 100644
> --- a/hw/vmware_vga.c
> +++ b/hw/vmware_vga.c
> @@ -995,7 +995,7 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s)
>  static void vmsvga_update_display(void *opaque)
>  {
>      struct vmsvga_state_s *s = opaque;
> -    DisplaySurface *surface = qemu_console_surface(s->vga.con);
> +    DisplaySurface *surface;
>      bool dirty = false;
>  
>      if (!s->enable) {
> @@ -1004,6 +1004,7 @@ static void vmsvga_update_display(void *opaque)
>      }
>  
>      vmsvga_check_size(s);
> +    surface = qemu_console_surface(s->vga.con);
>  
>      vmsvga_fifo_run(s);
>      vmsvga_update_rect_flush(s);
> -- 
> 1.7.9.7
> 
> 

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

* [Qemu-devel] [PATCH 19/24] console: gui timer fixes
  2013-04-16  9:39 [Qemu-devel] [PULL v4 00/24] console: console overhaul continued Gerd Hoffmann
@ 2013-04-16  9:39 ` Gerd Hoffmann
  0 siblings, 0 replies; 36+ messages in thread
From: Gerd Hoffmann @ 2013-04-16  9:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Make gui update rate adaption code in gui_update() actually work.
Sprinkle in a tracepoint so you can see the code at work.  Remove
the update rate adaption code in vnc and make vnc simply use the
generic bits instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |    9 ++++---
 trace-events         |    1 +
 ui/console.c         |   34 ++++++++++++++++++++----
 ui/sdl.c             |   10 +++----
 ui/vnc.c             |   71 ++++++++++++++------------------------------------
 ui/vnc.h             |    2 --
 6 files changed, 60 insertions(+), 67 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index f3e7791..3cb0018 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -21,7 +21,8 @@
 #define QEMU_CAPS_LOCK_LED   (1 << 2)
 
 /* in ms */
-#define GUI_REFRESH_INTERVAL 30
+#define GUI_REFRESH_INTERVAL_DEFAULT    30
+#define GUI_REFRESH_INTERVAL_IDLE     3000
 
 typedef void QEMUPutKBDEvent(void *opaque, int keycode);
 typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
@@ -174,8 +175,7 @@ typedef struct DisplayChangeListenerOps {
 } DisplayChangeListenerOps;
 
 struct DisplayChangeListener {
-    int idle;
-    uint64_t gui_timer_interval;
+    uint64_t update_interval;
     const DisplayChangeListenerOps *ops;
     DisplayState *ds;
 
@@ -207,12 +207,13 @@ static inline int is_buffer_shared(DisplaySurface *surface)
 
 void register_displaychangelistener(DisplayState *ds,
                                     DisplayChangeListener *dcl);
+void update_displaychangelistener(DisplayChangeListener *dcl,
+                                  uint64_t interval);
 void unregister_displaychangelistener(DisplayChangeListener *dcl);
 
 void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
 void dpy_gfx_replace_surface(QemuConsole *con,
                              DisplaySurface *surface);
-void dpy_refresh(DisplayState *s);
 void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
                   int dst_x, int dst_y, int w, int h);
 void dpy_text_cursor(QemuConsole *con, int x, int y);
diff --git a/trace-events b/trace-events
index b08627b..968edb6 100644
--- a/trace-events
+++ b/trace-events
@@ -965,6 +965,7 @@ dma_map_wait(void *dbs) "dbs=%p"
 console_gfx_new(void) ""
 console_txt_new(int w, int h) "%dx%d"
 console_select(int nr) "%d"
+console_refresh(int interval) "interval %d ms"
 displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
 displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
 displaysurface_free(void *display_surface) "surface=%p"
diff --git a/ui/console.c b/ui/console.c
index 79a306b..5bbc891 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -157,6 +157,9 @@ struct QemuConsole {
 
 struct DisplayState {
     struct QEMUTimer *gui_timer;
+    uint64_t last_update;
+    uint64_t update_interval;
+    bool refreshing;
     bool have_gfx;
     bool have_text;
 
@@ -171,22 +174,32 @@ static int nb_consoles = 0;
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
 static void dpy_gfx_switch_surface(DisplayState *ds,
                                    DisplaySurface *surface);
+static void dpy_refresh(DisplayState *s);
 
 static void gui_update(void *opaque)
 {
-    uint64_t interval = GUI_REFRESH_INTERVAL;
+    uint64_t interval = GUI_REFRESH_INTERVAL_IDLE;
+    uint64_t dcl_interval;
     DisplayState *ds = opaque;
     DisplayChangeListener *dcl;
 
+    ds->refreshing = true;
     dpy_refresh(ds);
+    ds->refreshing = false;
 
     QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->gui_timer_interval &&
-            dcl->gui_timer_interval < interval) {
-            interval = dcl->gui_timer_interval;
+        dcl_interval = dcl->update_interval ?
+            dcl->update_interval : GUI_REFRESH_INTERVAL_DEFAULT;
+        if (interval > dcl_interval) {
+            interval = dcl_interval;
         }
     }
-    qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
+    if (ds->update_interval != interval) {
+        ds->update_interval = interval;
+        trace_console_refresh(interval);
+    }
+    ds->last_update = qemu_get_clock_ms(rt_clock);
+    qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
 }
 
 static void gui_setup_refresh(DisplayState *ds)
@@ -1286,6 +1299,17 @@ void register_displaychangelistener(DisplayState *ds,
     }
 }
 
+void update_displaychangelistener(DisplayChangeListener *dcl,
+                                  uint64_t interval)
+{
+    DisplayState *ds = dcl->ds;
+
+    dcl->update_interval = interval;
+    if (!ds->refreshing && ds->update_interval > interval) {
+        qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+    }
+}
+
 void unregister_displaychangelistener(DisplayChangeListener *dcl)
 {
     DisplayState *ds = dcl->ds;
diff --git a/ui/sdl.c b/ui/sdl.c
index ede31dc..97764a6 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -751,12 +751,12 @@ static void handle_activation(SDL_Event *ev)
     if (ev->active.state & SDL_APPACTIVE) {
         if (ev->active.gain) {
             /* Back to default interval */
-            dcl->gui_timer_interval = 0;
-            dcl->idle = 0;
+            update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
         } else {
-            /* Sleeping interval */
-            dcl->gui_timer_interval = 500;
-            dcl->idle = 1;
+            /* Sleeping interval.  Not using the long default here as
+             * sdl_refresh does not only update the guest screen, but
+             * also checks for gui events. */
+            update_displaychangelistener(dcl, 500);
         }
     }
 }
diff --git a/ui/vnc.c b/ui/vnc.c
index bc787cc..75ad67f 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -34,9 +34,9 @@
 #include "qmp-commands.h"
 #include "qemu/osdep.h"
 
-#define VNC_REFRESH_INTERVAL_BASE 30
+#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
 #define VNC_REFRESH_INTERVAL_INC  50
-#define VNC_REFRESH_INTERVAL_MAX  2000
+#define VNC_REFRESH_INTERVAL_MAX  GUI_REFRESH_INTERVAL_IDLE
 static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
 static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
 
@@ -419,14 +419,12 @@ out_error:
 static int vnc_update_client(VncState *vs, int has_dirty);
 static int vnc_update_client_sync(VncState *vs, int has_dirty);
 static void vnc_disconnect_start(VncState *vs);
-static void vnc_init_timer(VncDisplay *vd);
-static void vnc_remove_timer(VncDisplay *vd);
 
 static void vnc_colordepth(VncState *vs);
 static void framebuffer_update_request(VncState *vs, int incremental,
                                        int x_position, int y_position,
                                        int w, int h);
-static void vnc_refresh(void *opaque);
+static void vnc_refresh(DisplayChangeListener *dcl);
 static int vnc_refresh_server_surface(VncDisplay *vd);
 
 static void vnc_dpy_update(DisplayChangeListener *dcl,
@@ -1064,11 +1062,6 @@ void vnc_disconnect_finish(VncState *vs)
         qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
     }
 
-    if (QTAILQ_EMPTY(&vs->vd->clients)) {
-        vs->vd->dcl.idle = 1;
-    }
-
-    vnc_remove_timer(vs->vd);
     if (vs->vd->lock_key_sync)
         qemu_remove_led_event_handler(vs->led);
     vnc_unlock_output(vs);
@@ -2013,9 +2006,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
     VncDisplay *vd = vs->vd;
 
     if (data[0] > 3) {
-        vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-        if (!qemu_timer_expired(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval))
-            qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
+        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
     }
 
     switch (data[0]) {
@@ -2647,18 +2638,16 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
     return has_dirty;
 }
 
-static void vnc_refresh(void *opaque)
+static void vnc_refresh(DisplayChangeListener *dcl)
 {
-    VncDisplay *vd = opaque;
+    VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
     VncState *vs, *vn;
     int has_dirty, rects = 0;
 
     graphic_hw_update(NULL);
 
     if (vnc_trylock_display(vd)) {
-        vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
-        qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) +
-                       vd->timer_interval);
+        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
         return;
     }
 
@@ -2670,39 +2659,21 @@ static void vnc_refresh(void *opaque)
         /* vs might be free()ed here */
     }
 
-    /* vd->timer could be NULL now if the last client disconnected,
-     * in this case don't update the timer */
-    if (vd->timer == NULL)
+    if (QTAILQ_EMPTY(&vd->clients)) {
+        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
         return;
+    }
 
     if (has_dirty && rects) {
-        vd->timer_interval /= 2;
-        if (vd->timer_interval < VNC_REFRESH_INTERVAL_BASE)
-            vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+        vd->dcl.update_interval /= 2;
+        if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
+            vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
+        }
     } else {
-        vd->timer_interval += VNC_REFRESH_INTERVAL_INC;
-        if (vd->timer_interval > VNC_REFRESH_INTERVAL_MAX)
-            vd->timer_interval = VNC_REFRESH_INTERVAL_MAX;
-    }
-    qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
-}
-
-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);
-        graphic_hw_update(NULL);
-        vnc_refresh(vd);
-    }
-}
-
-static void vnc_remove_timer(VncDisplay *vd)
-{
-    if (vd->timer != NULL && QTAILQ_EMPTY(&vd->clients)) {
-        qemu_del_timer(vd->timer);
-        qemu_free_timer(vd->timer);
-        vd->timer = NULL;
+        vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
+        if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
+            vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
+        }
     }
 }
 
@@ -2731,7 +2702,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket)
     }
 
     VNC_DEBUG("New client on socket %d\n", csock);
-    vd->dcl.idle = 0;
+    update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
     qemu_set_nonblock(vs->csock);
 #ifdef CONFIG_VNC_WS
     if (websocket) {
@@ -2787,8 +2758,6 @@ void vnc_init_state(VncState *vs)
     vs->mouse_mode_notifier.notify = check_pointer_type_change;
     qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
 
-    vnc_init_timer(vd);
-
     /* vs might be free()ed here */
 }
 
@@ -2829,6 +2798,7 @@ static void vnc_listen_websocket_read(void *opaque)
 
 static const DisplayChangeListenerOps dcl_ops = {
     .dpy_name          = "vnc",
+    .dpy_refresh       = vnc_refresh,
     .dpy_gfx_copy      = vnc_dpy_copy,
     .dpy_gfx_update    = vnc_dpy_update,
     .dpy_gfx_switch    = vnc_dpy_switch,
@@ -2840,7 +2810,6 @@ void vnc_display_init(DisplayState *ds)
 {
     VncDisplay *vs = g_malloc0(sizeof(*vs));
 
-    vs->dcl.idle = 1;
     vnc_display = vs;
 
     vs->lsock = -1;
diff --git a/ui/vnc.h b/ui/vnc.h
index 58e002e..ad1dec2 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -142,8 +142,6 @@ struct VncDisplay
     QTAILQ_HEAD(, VncState) clients;
     int num_exclusive;
     VncSharePolicy share_policy;
-    QEMUTimer *timer;
-    int timer_interval;
     int lsock;
 #ifdef CONFIG_VNC_WS
     int lwebsock;
-- 
1.7.9.7

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

end of thread, other threads:[~2013-04-16  9:40 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-04  7:28 [Qemu-devel] [PATCH v3 00/24] console: console overhaul continued Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 01/24] exynos4210_fimd.c: fix display resize bug introduced after console revamp Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 02/24] hw/vmware_vga.c: fix screen " Gerd Hoffmann
2013-04-05 11:21   ` Alexandru Damian
2013-04-04  7:28 ` [Qemu-devel] [PATCH 03/24] hw/vmware_vga.c: add tracepoints for mmio reads+writes Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 04/24] hw/vmware_vga.c: various vmware vga fixes Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 05/24] pixman: add qemu_pixman_color() Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 06/24] pixman: render vgafont glyphs into pixman images Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 07/24] console: use pixman for fill+blit Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 08/24] console: use pixman for font rendering Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 09/24] console: switch color_table_rgb to pixman_color_t Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 10/24] console: add trace events Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 11/24] console: displaystate init revamp Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 12/24] console: rename vga_hw_*, add QemuConsole param Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 13/24] console: give each QemuConsole its own DisplaySurface Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 14/24] console: simplify screendump Gerd Hoffmann
2013-04-04  7:28   ` Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 15/24] console: zap g_width + g_height Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 16/24] console: move gui_update+gui_setup_refresh from vl.c into console.c Gerd Hoffmann
2013-04-04  7:28 ` [Qemu-devel] [PATCH 17/24] console: make DisplayState private to console.c Gerd Hoffmann
2013-04-04  7:29 ` [Qemu-devel] [PATCH 18/24] console: add GraphicHwOps Gerd Hoffmann
2013-04-04  7:29   ` Gerd Hoffmann
2013-04-04  7:29 ` [Qemu-devel] [PATCH 19/24] console: gui timer fixes Gerd Hoffmann
2013-04-04  7:29 ` [Qemu-devel] [PATCH 20/24] xen: re-enable refresh interval reporting for xenfb Gerd Hoffmann
2013-04-04  7:29   ` Gerd Hoffmann
2013-04-04 17:06   ` [Qemu-devel] " Stefano Stabellini
2013-04-04 17:06     ` Stefano Stabellini
2013-04-05  7:28     ` [Qemu-devel] " Gerd Hoffmann
2013-04-05  7:28       ` Gerd Hoffmann
2013-04-05 10:07       ` [Qemu-devel] " Stefano Stabellini
2013-04-05 10:07         ` Stefano Stabellini
2013-04-04  7:29 ` [Qemu-devel] [PATCH 21/24] console: add qemu_console_is_* Gerd Hoffmann
2013-04-04  7:29 ` [Qemu-devel] [PATCH 22/24] console: allow pinning displaychangelisteners to consoles Gerd Hoffmann
2013-04-04  7:29 ` [Qemu-devel] [PATCH 23/24] gtk: custom cursor support Gerd Hoffmann
2013-04-04  7:29 ` [Qemu-devel] [PATCH 24/24] qxl: register QemuConsole for secondary cards Gerd Hoffmann
2013-04-16  9:39 [Qemu-devel] [PULL v4 00/24] console: console overhaul continued Gerd Hoffmann
2013-04-16  9:39 ` [Qemu-devel] [PATCH 19/24] console: gui timer fixes Gerd Hoffmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.