[Spice-commits] 3 commits - vdagent/desktop_layout.cpp vdagent/desktop_layout.h vdservice/vdservice.cpp

Arnon Gilboa agilboa at kemper.freedesktop.org
Thu Apr 28 01:52:59 PDT 2011


 vdagent/desktop_layout.cpp |  104 +++++++++++++++++++++++++++++++--------------
 vdagent/desktop_layout.h   |    1 
 vdservice/vdservice.cpp    |   23 ++++-----
 3 files changed, 84 insertions(+), 44 deletions(-)

New commits:
commit 6b74ffb8ebf429ffbd3280b330d46134a7ff4d6c
Author: Arnon Gilboa <agilboa at redhat.com>
Date:   Wed Mar 16 17:10:09 2011 +0200

    vdagent: remove dependency on qxl driver (rhbz#683166)
    
    -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

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);
commit 0d43d537c6abac743c12a1eb84541ef28fc24550
Author: Arnon Gilboa <agilboa at redhat.com>
Date:   Wed Mar 16 17:09:35 2011 +0200

    vdservice: support w2k3 32/64/r2, w2k8 32/64/r2 (rhbz#683166)

diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 85fa182..32c0ca5 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -132,8 +132,8 @@ VDService* VDService::get()
 
 enum SystemVersion {
     SYS_VER_UNSUPPORTED,
-    SYS_VER_WIN_XP,
-    SYS_VER_WIN_7,
+    SYS_VER_WIN_XP_CLASS, // also Server 2003/R2
+    SYS_VER_WIN_7_CLASS,  // also Server 2008/R2 & Vista
 };
 
 int supported_system_version()
@@ -146,11 +146,10 @@ int supported_system_version()
         vd_printf("GetVersionEx() failed: %u", GetLastError());
         return 0;
     }
-    if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
-        return SYS_VER_WIN_XP;
-    } else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1 &&
-                               osvi.wProductType == VER_NT_WORKSTATION) {
-        return SYS_VER_WIN_7;
+    if (osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion == 1 || osvi.dwMinorVersion == 2)) {
+        return SYS_VER_WIN_XP_CLASS;
+    } else if (osvi.dwMajorVersion == 6 && (osvi.dwMinorVersion == 0 || osvi.dwMinorVersion == 1)) {
+        return SYS_VER_WIN_7_CLASS;
     }
     return 0;
 }
@@ -535,9 +534,9 @@ bool VDService::execute()
             default:
                 if (wait_ret == WAIT_OBJECT_0 + _events_count - 1) {
                     vd_printf("Agent killed");
-                    if (_system_version == SYS_VER_WIN_XP) {
+                    if (_system_version == SYS_VER_WIN_XP_CLASS) {
                         restart_agent(false);
-                    } else if (_system_version == SYS_VER_WIN_7) {
+                    } else if (_system_version == SYS_VER_WIN_7_CLASS) {
                         kill_agent();
                     }
                 } else {
@@ -805,7 +804,7 @@ bool VDService::launch_agent()
     startup_info.cb = sizeof(startup_info);
     startup_info.lpDesktop = TEXT("Winsta0\\winlogon");
     ZeroMemory(&_agent_proc_info, sizeof(_agent_proc_info));
-    if (_system_version == SYS_VER_WIN_XP) {
+    if (_system_version == SYS_VER_WIN_XP_CLASS) {
         if (_session_id == 0) {
             ret = CreateProcess(_agent_path, _agent_path, NULL, NULL, FALSE, 0, NULL, NULL,
                                 &startup_info, &_agent_proc_info);
@@ -821,7 +820,7 @@ bool VDService::launch_agent()
                 Sleep(CREATE_PROC_INTERVAL_MS);
             }
         }
-    } else if (_system_version == SYS_VER_WIN_7) {
+    } else if (_system_version == SYS_VER_WIN_7_CLASS) {
         startup_info.lpDesktop = TEXT("Winsta0\\default");
         ret = create_process_as_user(_session_id, _agent_path, _agent_path, NULL, NULL, FALSE, 0,
                                      NULL, NULL, &startup_info, &_agent_proc_info);
commit bc74bd6e7983e94a1e0da773b6a4e288426ec5b2
Author: Arnon Gilboa <agilboa at redhat.com>
Date:   Mon Jan 31 19:21:42 2011 +0200

    vdservice: don't close pipe if overlapped I/O event is not in signaled state (rhbz#667777)
    
    which is beacuse ReadFile completed successfully without pending and the data was already consumed

diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 175587c..85fa182 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -512,7 +512,7 @@ bool VDService::execute()
                                             &bytes, FALSE) || GetLastError() == ERROR_MORE_DATA) {
                         handle_pipe_data(bytes);
                         read_pipe();
-                    } else {
+                    } else if (GetLastError() != ERROR_IO_INCOMPLETE) {
                         vd_printf("GetOverlappedResult failed %u", GetLastError());
                         _pipe_connected = false;
                         DisconnectNamedPipe(_pipe_state.pipe);


More information about the Spice-commits mailing list