[Spice-devel] [win32-qxl PATCH v3] Add monitors_config escape to Windows QXL display driver.

Sandy Stutsman sstutsma at redhat.com
Wed Jun 24 11:29:15 PDT 2015


Provides correct monitor locations when specified via the guest
"Screen Resolution" applet.

Addresses:https://bugzilla.redhat.com/show_bug.cgi?id=1202419
---
Changes from v1 and v2
  Remove misc typo fixes
  Reuse existing QXLHead structure instead driver specific escape structure
---
 xddm/display/driver.c     | 34 ++++++++++++++++++++++++++++++++++
 xddm/display/qxldd.h      |  4 ++++
 xddm/display/res.c        | 14 ++++++++++++++
 xddm/include/qxl_driver.h |  6 +++++-
 xddm/miniport/qxl.c       |  3 +++
 5 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/xddm/display/driver.c b/xddm/display/driver.c
index aa4fe42..acc4987 100644
--- a/xddm/display/driver.c
+++ b/xddm/display/driver.c
@@ -253,6 +253,26 @@ BOOL DrvEnableDriver(ULONG engine_version, ULONG enable_data_size, PDRVENABLEDAT
     return TRUE;
 }
 
+static void SetMonitorConfig(PDev *pdev,    QXLHead * esc_config)
+{
+    QXLMonitorsConfig   *monitorConfig;
+    QXLHead             *heads;
+
+    pdev->monitor_config->count = 1;
+    pdev->monitor_config->max_allowed = 1;
+
+    heads = &pdev->monitor_config->heads[0];
+    heads->id = 0;
+    heads->surface_id = 0;
+    heads->x = esc_config->x;
+    heads->y = esc_config->y;
+    heads->width = esc_config->width;
+    heads->height = esc_config->height;
+    DEBUG_PRINT((pdev, 2, "%s Monitor %d (%d, %d) (%d x %d)\n",
+        __FUNCTION__, pdev->dev_id, heads->x, heads->y, heads->width, heads->height));
+    async_io(pdev, ASYNCABLE_MONITOR_CONFIG, 0);
+}
+
 ULONG DrvEscape(SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn,
                 ULONG cjOut, PVOID pvOut)
 {
@@ -275,6 +295,16 @@ ULONG DrvEscape(SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn,
         RetVal = 1;
         break;
     }
+    case QXL_ESCAPE_MONITOR_CONFIG: {
+        ULONG length;
+        DEBUG_PRINT((pdev, 2, "%s - 0x%p \n", __FUNCTION__, pdev));
+        if (pdev == NULL || cjIn != sizeof(QXLHead))
+            break;
+
+        SetMonitorConfig(pdev, (QXLHead * )pvIn);
+        RetVal = 1;
+        break;
+    }
     default:
         DEBUG_PRINT((NULL, 1, "%s: unhandled escape code %d\n", __FUNCTION__, iEsc));
         RetVal = 0;
@@ -774,6 +804,9 @@ static BOOL PrepareHardware(PDev *pdev)
     pdev->asyncable[ASYNCABLE_FLUSH_SURFACES][ASYNC] = dev_info.flush_surfaces_async_port;
     pdev->asyncable[ASYNCABLE_FLUSH_SURFACES][SYNC] = NULL;
 
+    pdev->asyncable[ASYNCABLE_MONITOR_CONFIG][ASYNC] = dev_info.monitors_config_port;
+    pdev->asyncable[ASYNCABLE_MONITOR_CONFIG][SYNC] = NULL;
+
     pdev->display_event = dev_info.display_event;
     pdev->cursor_event = dev_info.cursor_event;
     pdev->sleep_event = dev_info.sleep_event;
@@ -847,6 +880,7 @@ static BOOL PrepareHardware(PDev *pdev)
     DEBUG_PRINT((pdev, 1, "%s: create_non_primary_surfaces = %d\n", __FUNCTION__,
                  pdev->create_non_primary_surfaces));
 
+    pdev->monitor_config_pa = dev_info.monitors_config;
     CreateVRamSlot(pdev);
 
     DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit: 0x%lx %ul\n", __FUNCTION__, pdev,
diff --git a/xddm/display/qxldd.h b/xddm/display/qxldd.h
index a0b2eab..9ce5243 100644
--- a/xddm/display/qxldd.h
+++ b/xddm/display/qxldd.h
@@ -180,6 +180,7 @@ typedef enum {
     ASYNCABLE_DESTROY_SURFACE,
     ASYNCABLE_DESTROY_ALL_SURFACES,
     ASYNCABLE_FLUSH_SURFACES,
+    ASYNCABLE_MONITOR_CONFIG,
 
     ASYNCABLE_COUNT
 } asyncable_t;
@@ -349,6 +350,9 @@ typedef struct PDev {
 
     UCHAR  pci_revision;
 
+    QXLMonitorsConfig * monitor_config;
+    QXLPHYSICAL * monitor_config_pa;
+
 #ifdef DBG
     int num_free_pages;
     int num_outputs;
diff --git a/xddm/display/res.c b/xddm/display/res.c
index bfb3571..7c65e29 100644
--- a/xddm/display/res.c
+++ b/xddm/display/res.c
@@ -548,12 +548,26 @@ void ClearResources(PDev *pdev)
     }
 }
 
+/*
+ * Tell the spice server where to look for updates to the monitor configuration.
+ */
+void InitMonitorConfig(PDev *pdev)
+{
+    size_t monitor_config_size   = sizeof(QXLMonitorsConfig) + sizeof(QXLHead);
+
+    pdev->monitor_config      = AllocMem(pdev, MSPACE_TYPE_DEVRAM, monitor_config_size);
+    RtlZeroMemory(pdev->monitor_config, monitor_config_size);
+
+    *pdev->monitor_config_pa  = PA(pdev, pdev->monitor_config, pdev->main_mem_slot);
+}
+
 void InitResources(PDev *pdev)
 {
     DEBUG_PRINT((pdev, 3, "%s: entry\n", __FUNCTION__));
 
     InitSurfaces(pdev);
     InitDeviceMemoryResources(pdev);
+    InitMonitorConfig(pdev);
 
     pdev->update_id = *pdev->dev_update_id;
 
diff --git a/xddm/include/qxl_driver.h b/xddm/include/qxl_driver.h
index 677ee17..0ed73c4 100644
--- a/xddm/include/qxl_driver.h
+++ b/xddm/include/qxl_driver.h
@@ -32,7 +32,8 @@
 enum {
     FIRST_AVIL_IOCTL_FUNC = 0x800,
     QXL_GET_INFO_FUNC = FIRST_AVIL_IOCTL_FUNC,
-    QXL_SET_CUSTOM_DISPLAY
+    QXL_SET_CUSTOM_DISPLAY,
+    QXL_SET_MONITOR_CONFIG
 };
 
 #define IOCTL_QXL_GET_INFO \
@@ -109,6 +110,7 @@ typedef struct QXLDriverInfo {
     PUCHAR memslot_add_port;
     PUCHAR memslot_del_port;
     PUCHAR destroy_all_surfaces_port;
+    PUCHAR monitors_config_port;
 
     UCHAR  pci_revision;
 
@@ -121,6 +123,8 @@ typedef struct QXLDriverInfo {
     UINT64 fb_phys;
 
     UINT8 create_non_primary_surfaces;
+
+    QXLPHYSICAL * monitors_config;
 } QXLDriverInfo;
 
 #endif
diff --git a/xddm/miniport/qxl.c b/xddm/miniport/qxl.c
index f5d6b48..e0fb87f 100644
--- a/xddm/miniport/qxl.c
+++ b/xddm/miniport/qxl.c
@@ -1246,6 +1246,7 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet)
             driver_info->destroy_primary_port = dev_ext->io_port + QXL_IO_DESTROY_PRIMARY;
             driver_info->memslot_add_port = dev_ext->io_port + QXL_IO_MEMSLOT_ADD;
             driver_info->memslot_del_port = dev_ext->io_port + QXL_IO_MEMSLOT_DEL;
+            driver_info->monitors_config_port = dev_ext->io_port + QXL_IO_MONITORS_CONFIG_ASYNC;
 
             driver_info->primary_surface_create = &dev_ext->ram_header->create_surface;
 
@@ -1256,6 +1257,8 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet)
             driver_info->dev_id = dev_ext->rom->id;
 
             driver_info->create_non_primary_surfaces = check_non_primary_surfaces_registry_key(dev_ext);
+
+            driver_info->monitors_config = &dev_ext->ram_header->monitors_config;
         }
         break;
 
-- 
1.9.5.msysgit.0



More information about the Spice-devel mailing list