[Spice-devel] [PATCH vdagent-win] vdagent: fix cursor position sync on multimon rhbz#757819

Alon Levy alevy at redhat.com
Wed Feb 1 06:58:31 PST 2012


On Wed, Feb 01, 2012 at 04:38:44PM +0200, Arnon Gilboa wrote:
> Alon Levy wrote:
> >On Wed, Feb 01, 2012 at 10:48:29AM +0200, Arnon Gilboa wrote:
> >>Thanks Alon, adding these lines to the comment:
> >>
> >>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, see:
> >>_input.mi.dx = (mode->get_pos_x() + _mouse_x) * 0xffff /
> >>_desktop_layout->get_total_width();
> >>_input.mi.dy = (mode->get_pos_y() + _mouse_y) * 0xffff /
> >>_desktop_layout->get_total_height();
> >>
> >>Is it clear now?
> >
> >That wasn't the point. I wasn't talking about what goes wrong with the
> >computation, I was talking about what sequence of events leads to the
> >client sending monitors locations that are negatively offset to the origin.
> >
> >Anyway, if you already wrote it it wouldn't hurt to be in the commit
> >message I guess :)
> >
> Primary monitor is always located (in windows, what about linux?) in
> (0,0). When you position a secondary monitor 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's VD_AGENT_MONITORS_CONFIG)
> from the client to the agent.
> 
> Does it answer your question? :/

Yes, it does. Why the sour face?

> 
> >>Alon Levy wrote:
> >>>On Mon, Jan 23, 2012 at 12:59:22PM +0200, Arnon Gilboa wrote:
> >>>>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.
> >>>Looks good, but can you give a better example of how something goes
> >>>wrong in the patch comment?
> >>>
> >>>ACK
> >>>
> >>>>---
> >>>>vdagent/desktop_layout.cpp |   52 +++++++++++++++++++++++++++----------------
> >>>>vdagent/desktop_layout.h   |    1 +
> >>>>2 files changed, 34 insertions(+), 19 deletions(-)
> >>>>
> >>>>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);
> >>>>-- 
> >>>>1.7.4.1
> >>>>
> >>>>_______________________________________________
> >>>>Spice-devel mailing list
> >>>>Spice-devel at lists.freedesktop.org
> >>>>http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list