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

Uri Lublin uril at kemper.freedesktop.org
Wed Jun 10 04:28:50 PDT 2015


 vdagent/desktop_layout.cpp |   31 +++++++++++++++++++++++++++----
 vdagent/desktop_layout.h   |    7 ++++++-
 2 files changed, 33 insertions(+), 5 deletions(-)

New commits:
commit 7bac272308469d1da9b3026306679b31ccaa371b
Author: Sandy Stutsman <sstutsma at redhat.com>
Date:   Fri Jun 5 18:54:48 2015 -0400

    Use (0,0) for Windows Primary monitors.
    
    Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1174129.
    
    Windows considers the monitor positioned at (0,0) to be primary. VDAgent
    normalizes the monitor positions so that there are no negative
    coordinates. If the normalized positions are passed to the Windows APIs,
    the leftmost monitor will always be set to primary. We need to keep
    track of the original primary monitor and its normalized position to be
    able to adjust the coordinates that are passed to Windows.

diff --git a/vdagent/desktop_layout.cpp b/vdagent/desktop_layout.cpp
index 7850e6d..f71abd0 100644
--- a/vdagent/desktop_layout.cpp
+++ b/vdagent/desktop_layout.cpp
@@ -90,6 +90,21 @@ void DesktopLayout::get_displays()
     unlock();
 }
 
+DisplayMode * DesktopLayout::get_primary_display()
+{
+    DisplayMode * mode;
+
+    for (unsigned int i = 0; i < get_display_count(); i++)
+    {
+        mode = _displays.at(i);
+        if (!mode)
+            continue;
+        if (mode->is_primary())
+            return mode;
+    }
+    return NULL;
+}
+
 void DesktopLayout::set_displays()
 {
     DISPLAY_DEVICE dev_info;
@@ -107,6 +122,12 @@ void DesktopLayout::set_displays()
     dev_info.cb = sizeof(dev_info);
     ZeroMemory(&dev_mode, sizeof(dev_mode));
     dev_mode.dmSize = sizeof(dev_mode);
+
+    //Get the normalized position of the primary monitor
+    DisplayMode * primary(get_primary_display());
+    LONG normal_x = primary ? primary->get_pos_x() : 0;
+    LONG normal_y = primary ? primary->get_pos_y() : 0;
+
     while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) {
         dev_id++;
         if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) {
@@ -121,7 +142,8 @@ void DesktopLayout::set_displays()
             vd_printf("display_id %lu out of range, #displays %zu" , display_id, _displays.size());
             break;
         }
-        if (!init_dev_mode(dev_info.DeviceName, &dev_mode, _displays.at(display_id), true)) {
+        if (!init_dev_mode(dev_info.DeviceName, &dev_mode, _displays.at(display_id),
+                           normal_x, normal_y, true)) {
             vd_printf("No suitable mode found for display %S", dev_info.DeviceName);
             break;
         }
@@ -240,7 +262,7 @@ bool DesktopLayout::get_qxl_device_id(WCHAR* device_key, DWORD* device_id)
 }
 
 bool DesktopLayout::init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, DisplayMode* mode,
-                                  bool set_pos)
+                                  LONG normal_x, LONG normal_y, bool set_pos)
 {
     DWORD closest_diff = -1;
     DWORD best = -1;
@@ -320,8 +342,9 @@ bool DesktopLayout::init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, DisplayMo
     }
     dev_mode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
     if (set_pos) {
-        dev_mode->dmPosition.x = mode->_pos_x;
-        dev_mode->dmPosition.y = mode->_pos_y;
+        //Convert the position so that the primary is always at (0,0)
+        dev_mode->dmPosition.x = mode->_pos_x - normal_x;
+        dev_mode->dmPosition.y = mode->_pos_y - normal_y;
         dev_mode->dmFields |= DM_POSITION;
     }
 
diff --git a/vdagent/desktop_layout.h b/vdagent/desktop_layout.h
index c43ff03..4f6a042 100644
--- a/vdagent/desktop_layout.h
+++ b/vdagent/desktop_layout.h
@@ -31,6 +31,7 @@ public:
         , _depth (depth)
         , _attached (attached)
     {
+        _primary = (pos_x == 0 && pos_y == 0 && attached);
     }
 
     LONG get_pos_x() { return _pos_x;}
@@ -44,6 +45,7 @@ public:
     void set_res(DWORD width, DWORD height, DWORD depth);
     void set_depth(DWORD depth) { _depth = depth;}
     void set_attached(bool attached) { _attached = attached;}
+    bool is_primary() { return _primary; }
 
 private:
     LONG _pos_x;
@@ -52,6 +54,7 @@ private:
     DWORD _height;
     DWORD _depth;
     bool _attached;
+    bool _primary;
 
     friend class DesktopLayout;
 };
@@ -74,10 +77,12 @@ public:
 private:
     void clean_displays();
     void normalize_displays_pos();
+    DisplayMode * get_primary_display();
     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);
+    static bool init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, DisplayMode* mode,
+                              LONG normal_x, LONG normal_y, bool set_pos);
 
 private:
     mutex_t _mutex;


More information about the Spice-commits mailing list