[Spice-devel] [PATCH 3/3] vdagent: remove dependency on qxl driver (rhbz#683166)

Arnon Gilboa agilboa at redhat.com
Thu Apr 28 01:58:42 PDT 2011


-don't fail to start when no qxl driver installed
-if qxls found use them, otherwise just use enumerated non-mirror devices
-currently qxl/non-qxl multimon mix is not supported
---
 vdagent/desktop_layout.cpp |  104 ++++++++++++++++++++++++++++++-------------
 vdagent/desktop_layout.h   |    1 +
 2 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/vdagent/desktop_layout.cpp b/vdagent/desktop_layout.cpp
index 010d821..9bd1852 100644
--- a/vdagent/desktop_layout.cpp
+++ b/vdagent/desktop_layout.cpp
@@ -42,7 +42,7 @@ void DesktopLayout::get_displays()
 {
     DISPLAY_DEVICE dev_info;
     DEVMODE mode;
-    DWORD qxl_id;
+    DWORD display_id;
     DWORD dev_id = 0;
     LONG min_x = 0;
     LONG min_y = 0;
@@ -51,37 +51,44 @@ void DesktopLayout::get_displays()
     bool attached;
 
     lock();
+    if (!consistent_displays()) {
+        unlock();
+        return;
+    }
     clean_displays();
     ZeroMemory(&dev_info, sizeof(dev_info));
     dev_info.cb = sizeof(dev_info);
     ZeroMemory(&mode, sizeof(mode));
     mode.dmSize = sizeof(mode);
     while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) {
-        if (wcsstr(dev_info.DeviceString, L"QXL")) {
-            attached = !!(dev_info.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP);
-            EnumDisplaySettings(dev_info.DeviceName, ENUM_CURRENT_SETTINGS, &mode);
-            if (!get_qxl_device_id(dev_info.DeviceKey, &qxl_id)) {
-                vd_printf("get_qxl_device_id failed");
-                break;
-            }
-            size_t size = _displays.size();
-            if (qxl_id >= size) {
-                _displays.resize(qxl_id + 1);
-                for (size_t i = size; i < qxl_id; i++) {
-                    _displays[i] = NULL;
-                }
-            }
-            _displays[qxl_id] = new DisplayMode(mode.dmPosition.x, mode.dmPosition.y,
-                                                mode.dmPelsWidth, mode.dmPelsHeight,
-                                                mode.dmBitsPerPel, attached);
-            if (attached) {
-                min_x = min(min_x, mode.dmPosition.x);
-                min_y = min(min_y, mode.dmPosition.y);
-                max_x = max(max_x, mode.dmPosition.x + (LONG)mode.dmPelsWidth);
-                max_y = max(max_y, mode.dmPosition.y + (LONG)mode.dmPelsHeight);
+        dev_id++;
+        if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) {
+            continue;
+        }
+        size_t size = _displays.size();
+        if (!wcsstr(dev_info.DeviceString, L"QXL")) {
+            display_id = size;
+        } else if (!get_qxl_device_id(dev_info.DeviceKey, &display_id)) {
+            vd_printf("get_qxl_device_id failed %S", dev_info.DeviceKey);
+            break;
+        }
+        if (display_id >= size) {
+            _displays.resize(display_id + 1);
+            for (size_t i = size; i < display_id; i++) {
+                _displays[i] = NULL;
             }
         }
-        dev_id++;
+        attached = !!(dev_info.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP);
+        EnumDisplaySettings(dev_info.DeviceName, ENUM_CURRENT_SETTINGS, &mode);
+        _displays[display_id] = new DisplayMode(mode.dmPosition.x, mode.dmPosition.y,
+                                            mode.dmPelsWidth, mode.dmPelsHeight,
+                                            mode.dmBitsPerPel, attached);
+        if (attached) {
+            min_x = min(min_x, mode.dmPosition.x);
+            min_y = min(min_y, mode.dmPosition.y);
+            max_x = max(max_x, mode.dmPosition.x + (LONG)mode.dmPelsWidth);
+            max_y = max(max_y, mode.dmPosition.y + (LONG)mode.dmPelsHeight);
+        }
     }
     if (min_x || min_y) {
         for (Displays::iterator iter = _displays.begin(); iter != _displays.end(); iter++) {
@@ -98,27 +105,33 @@ void DesktopLayout::set_displays()
     DISPLAY_DEVICE dev_info;
     DEVMODE dev_mode;
     DWORD dev_id = 0;
-    DWORD qxl_id = 0;
+    DWORD display_id = 0;
     int dev_sets = 0;
 
     lock();
+    if (!consistent_displays()) {
+        unlock();
+        return;
+    }
     ZeroMemory(&dev_info, sizeof(dev_info));
     dev_info.cb = sizeof(dev_info);
     ZeroMemory(&dev_mode, sizeof(dev_mode));
     dev_mode.dmSize = sizeof(dev_mode);
-    while (EnumDisplayDevices(NULL, dev_id++, &dev_info, 0)) {
-        if (!wcsstr(dev_info.DeviceString, L"QXL")) {
+    while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) {
+        dev_id++;
+        if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) {
             continue;
         }
-        if (!get_qxl_device_id(dev_info.DeviceKey, &qxl_id)) {
-            vd_printf("get_qxl_device_id failed");
+        bool is_qxl = !!wcsstr(dev_info.DeviceString, L"QXL");
+        if (is_qxl && !get_qxl_device_id(dev_info.DeviceKey, &display_id)) {
+            vd_printf("get_qxl_device_id failed %S", dev_info.DeviceKey);
             break;
         }
-        if (qxl_id >= _displays.size()) {
-            vd_printf("qxl_id %u out of range, #displays %u", qxl_id, _displays.size());
+        if (display_id >= _displays.size()) {
+            vd_printf("display_id %u out of range, #displays %u", display_id, _displays.size());
             break;
         }
-        if (!init_dev_mode(dev_info.DeviceName, &dev_mode, _displays.at(qxl_id), true)) {
+        if (!init_dev_mode(dev_info.DeviceName, &dev_mode, _displays.at(display_id), true)) {
             vd_printf("No suitable mode found for display %S", dev_info.DeviceName);
             break;
         }
@@ -128,6 +141,9 @@ void DesktopLayout::set_displays()
         if (ret == DISP_CHANGE_SUCCESSFUL) {
             dev_sets++;
         }
+        if (!is_qxl) {
+            display_id++;
+        }
     }
     if (dev_sets) {
         ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
@@ -135,6 +151,30 @@ void DesktopLayout::set_displays()
     unlock();
 }
 
+bool DesktopLayout::consistent_displays()
+{
+    DISPLAY_DEVICE dev_info;
+    DWORD dev_id = 0;
+    int non_qxl_count = 0;
+    int qxl_count = 0;
+
+    ZeroMemory(&dev_info, sizeof(dev_info));
+    dev_info.cb = sizeof(dev_info);
+    while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) {
+        dev_id++;
+        if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) {
+            continue;
+        }
+        if (wcsstr(dev_info.DeviceString, L"QXL")) {
+            qxl_count++;
+        } else {
+            non_qxl_count++;
+        }
+    }
+    vd_printf("#qxls %d #others %d", qxl_count, non_qxl_count);
+    return (!qxl_count || !non_qxl_count);
+}
+
 void DesktopLayout::clean_displays()
 {
     lock();
diff --git a/vdagent/desktop_layout.h b/vdagent/desktop_layout.h
index f3294b5..caab84f 100644
--- a/vdagent/desktop_layout.h
+++ b/vdagent/desktop_layout.h
@@ -73,6 +73,7 @@ public:
 
 private:
     void clean_displays();
+    static bool consistent_displays();
     static bool is_attached(LPCTSTR dev_name);
     static bool get_qxl_device_id(WCHAR* device_key, DWORD* device_id);
     static bool init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, DisplayMode* mode, bool set_pos);
-- 
1.7.4.1



More information about the Spice-devel mailing list