diff mbox series

[24/29] vmsvga: Add support for SVGA_FIFO_CAP_CURSOR_BYPASS_3

Message ID 1533815202-11967-25-git-send-email-liran.alon@oracle.com (mailing list archive)
State New, archived
Headers show
Series : vmsvga: Various fixes and enhancements | expand

Commit Message

Liran Alon Aug. 9, 2018, 11:46 a.m. UTC
From: Leonid Shatz <leonid.shatz@oracle.com>

This adds tracking of guest cursor position with the help of FIFO
registers reporting pointing device coordindates.

Signed-off-by: Leonid Shatz <leonid.shatz@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Signed-off-by: Liran Alon <liran.alon@oracle.com>
---
 hw/display/vmware_vga.c | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 49b46938207e..1db8f92f053b 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -51,6 +51,7 @@  struct vmsvga_state_s {
         int y;
         int on;
     } cursor;
+    uint32_t last_fifo_cursor_count;
 
     int index;
     int scratch_size;
@@ -326,6 +327,7 @@  enum {
 #define SVGA_FIFO_CAP_FENCE             (1 << 0)
 #define SVGA_FIFO_CAP_ACCELFRONT        (1 << 1)
 #define SVGA_FIFO_CAP_PITCHLOCK         (1 << 2)
+#define SVGA_FIFO_CAP_CURSOR_BYPASS_3   (1 << 4)
 
 #define SVGA_FIFO_FLAG_NONE             0
 #define SVGA_FIFO_FLAG_ACCELFRONT       (1 << 0)
@@ -417,6 +419,35 @@  enum {
     SVGA_CURSOR_ON_RESTORE_TO_FB = 3,
 };
 
+/* Update cursor position from SVGA_FIFO_CURSOR registers */
+static void cursor_update_from_fifo(struct vmsvga_state_s *s)
+{
+    uint32_t fifo_cursor_count;
+    uint32_t on_off;
+
+    if (!s->config || !s->enable) {
+        return;
+    }
+
+    if (s->fifo_min <= SVGA_FIFO_CURSOR_LAST_UPDATED) {
+        return;
+    }
+
+    fifo_cursor_count = s->fifo[SVGA_FIFO_CURSOR_COUNT];
+    if (fifo_cursor_count == s->last_fifo_cursor_count)
+        return;
+
+    s->last_fifo_cursor_count = fifo_cursor_count;
+    on_off = s->fifo[SVGA_FIFO_CURSOR_ON] ? SVGA_CURSOR_ON_SHOW : SVGA_CURSOR_ON_HIDE;
+    s->cursor.on = on_off;
+    s->cursor.x = s->fifo[SVGA_FIFO_CURSOR_X];
+    s->cursor.y = s->fifo[SVGA_FIFO_CURSOR_Y];
+
+#ifdef HW_MOUSE_ACCEL
+    dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on);
+#endif
+}
+
 static inline bool vmsvga_verify_rect(DisplaySurface *surface,
                                       const char *name,
                                       int x, int y, int w, int h)
@@ -1423,6 +1454,7 @@  static void vmsvga_update_display(void *opaque)
 
     vmsvga_fifo_run(s);
     vmsvga_update_rect_flush(s);
+    cursor_update_from_fifo(s);
 
     if (s->invalidated) {
         s->invalidated = 0;
@@ -1446,6 +1478,7 @@  static void vmsvga_reset(DeviceState *dev)
     s->syncing = 0;
     s->irq_mask = 0;
     s->irq_status = 0;
+    s->last_fifo_cursor_count = 0;
 
     vga_dirty_log_start(&s->vga);
 }
@@ -1479,6 +1512,7 @@  static int vmsvga_post_load(void *opaque, int version_id)
     if (version_id < 1) {
         s->irq_mask = 0;
         s->irq_status = 0;
+        s->last_fifo_cursor_count = 0;
     }
 
     return 0;
@@ -1508,6 +1542,7 @@  static const VMStateDescription vmstate_vmware_vga_internal = {
         VMSTATE_UNUSED(4), /* was fb_size */
         VMSTATE_UINT32_V(irq_mask, struct vmsvga_state_s, 1),
         VMSTATE_UINT32_V(irq_status, struct vmsvga_state_s, 1),
+        VMSTATE_UINT32_V(last_fifo_cursor_count, struct vmsvga_state_s, 1),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -1543,7 +1578,8 @@  static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,
                            &error_fatal);
     s->fifo = (uint32_t *)memory_region_get_ram_ptr(&s->fifo_ram);
     s->num_fifo_regs = SVGA_FIFO_NUM_REGS;
-    s->fifo[SVGA_FIFO_CAPABILITIES] = SVGA_FIFO_CAP_FENCE;
+    s->fifo[SVGA_FIFO_CAPABILITIES] =
+        SVGA_FIFO_CAP_FENCE | SVGA_FIFO_CAP_CURSOR_BYPASS_3;
     s->fifo[SVGA_FIFO_FLAGS] = 0;
 
     vga_common_init(&s->vga, OBJECT(dev));