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

Arnon Gilboa agilboa at kemper.freedesktop.org
Sun Feb 5 02:00:48 PST 2012


 vdagent/desktop_layout.cpp |   52 ++++++++++++++++++++++++++++-----------------
 vdagent/desktop_layout.h   |    1 
 2 files changed, 34 insertions(+), 19 deletions(-)

New commits:
commit b127e5fdae0c95115a5c1f2223593adf64dd5cf7
Author: Arnon Gilboa <agilboa at redhat.com>
Date:   Wed Jan 4 12:52:15 2012 +0200

    vdagent: fix cursor position sync on multimon rhbz#757819
    
    On any change of the display settings, driven by client message or guest user,
    normalize all display positions to non-negative coordinates, and update total
    width and height of the virtual desktop. The bug was due to wrong handling of
    (non-primary) displays positioned on negative coordinates.
    
    Primary monitor is always located (in windows) in (0,0). When a secondary
    monitor is positioned above/to the left of the primary, it will have negative
    coordinate. This can be the case when guest display settings are changed either
    manually on the guest, or due to a message (auto-conf VD_AGENT_MONITORS_CONFIG)
    from the client to the agent.
    
    In VDAgent::handle_mouse_event(), mouse event is generated by scaling the
    received (x,y, display_id) to normalized absolute coordinates (0..0xffff) on
    the entire virtual desktop which contains all the displays. Keeping negative
    display coordinates, as received from the client, was mistakenly handled and
    generated wrong (sometimes even negative) coordinates.

diff --git a/vdagent/desktop_layout.cpp b/vdagent/desktop_layout.cpp
index 0eada52..0ba7248 100644
--- a/vdagent/desktop_layout.cpp
+++ b/vdagent/desktop_layout.cpp
@@ -44,10 +44,6 @@ void DesktopLayout::get_displays()
     DEVMODE mode;
     DWORD display_id;
     DWORD dev_id = 0;
-    LONG min_x = 0;
-    LONG min_y = 0;
-    LONG max_x = 0;
-    LONG max_y = 0;
     bool attached;
 
     lock();
@@ -81,22 +77,10 @@ void DesktopLayout::get_displays()
         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++) {
-            (*iter)->move_pos(-min_x, -min_y);
-        }
+                                                mode.dmPelsWidth, mode.dmPelsHeight,
+                                                mode.dmBitsPerPel, attached);
     }
-    _total_width = max_x - min_x;
-    _total_height = max_y - min_y;
+    normalize_displays_pos();
     unlock();
 }
 
@@ -147,10 +131,40 @@ void DesktopLayout::set_displays()
     }
     if (dev_sets) {
         ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
+        normalize_displays_pos();
     }
     unlock();
 }
 
+// Normalize all display positions to non-negative coordinates and update total width and height of
+// the virtual desktop. Caller is responsible to lock() & unlock().
+void DesktopLayout::normalize_displays_pos()
+{
+    Displays::iterator iter;
+    DisplayMode* mode;
+    LONG min_x = 0;
+    LONG min_y = 0;
+    LONG max_x = 0;
+    LONG max_y = 0;
+
+    for (iter = _displays.begin(); iter != _displays.end(); iter++) {
+        mode = *iter;
+        if (mode->_attached) {
+            min_x = min(min_x, mode->_pos_x);
+            min_y = min(min_y, mode->_pos_y);
+            max_x = max(max_x, mode->_pos_x + (LONG)mode->_width);
+            max_y = max(max_y, mode->_pos_y + (LONG)mode->_height);
+        }
+    }
+    if (min_x || min_y) {
+        for (iter = _displays.begin(); iter != _displays.end(); iter++) {
+            (*iter)->move_pos(-min_x, -min_y);
+        }
+    }
+    _total_width = max_x - min_x;
+    _total_height = max_y - min_y;
+}
+
 bool DesktopLayout::consistent_displays()
 {
     DISPLAY_DEVICE dev_info;
diff --git a/vdagent/desktop_layout.h b/vdagent/desktop_layout.h
index caab84f..c43ff03 100644
--- a/vdagent/desktop_layout.h
+++ b/vdagent/desktop_layout.h
@@ -73,6 +73,7 @@ public:
 
 private:
     void clean_displays();
+    void normalize_displays_pos();
     static bool consistent_displays();
     static bool is_attached(LPCTSTR dev_name);
     static bool get_qxl_device_id(WCHAR* device_key, DWORD* device_id);


More information about the Spice-commits mailing list