[Spice-devel] Fwd: [vdagent-win PATCH] Use Windows coordinates with primary monitor at (0, 0) when making WinAPI calls.
Uri Lublin
uril at redhat.com
Wed Mar 25 11:01:42 PDT 2015
On 03/21/2015 01:06 AM, Sandy Stutsman wrote:
> From: Sandy Stutsman <sstutsma at redhat.com>
>
Hi Sandy,
Looks good.
I have some comments below.
I'll try to test it tomorrow.
> Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1174129. Windows
> sets the monitor positioned at (0,0) to be the primary monitor.
> While VDAgent normalizes the monitor positions so that there no negative
> coordinates. If the normalized positions passed to the Windows APIs,
> the leftmost monitor will always be set to primary. We need to keep
> track of the primary monitor and its normalized position to be able to
> adjust the monitor coordinates that are passed to Windows.
> ---
> vdagent/desktop_layout.cpp | 34 ++++++++++++++++++++++++++++++----
> vdagent/desktop_layout.h | 8 +++++---
> 2 files changed, 35 insertions(+), 7 deletions(-)
> mode change 100644 => 100755 vdagent/desktop_layout.cpp
>
> diff --git a/vdagent/desktop_layout.cpp b/vdagent/desktop_layout.cpp
> old mode 100644
> new mode 100755
> index 7850e6d..1f82f2d
> --- a/vdagent/desktop_layout.cpp
> +++ b/vdagent/desktop_layout.cpp
> @@ -90,6 +90,23 @@ void DesktopLayout::get_displays()
> unlock();
> }
>
> +DisplayMode * DesktopLayout::get_primary_display()
> +{
> + DisplayMode * mode;
> + boolean bFound(false);
bFound is not used.
> + for (unsigned int i = 0; i < get_display_count(); i++)
> + {
> + mode = _displays.at(i);
> + if (!mode)
> + return mode;
Maybe better to "continue" here and check all displays.
> + if (mode->is_primary())
> + return mode;
> + }
> +
> + //Default to the first display
> + return _displays.at(0);
And here we can return NULL, if primary is not found.
(Just for consistency with "return mode" above if
that line is not changed. Returning the first display
should work)
> +}
> +
> void DesktopLayout::set_displays()
> {
> DISPLAY_DEVICE dev_info;
> @@ -107,6 +124,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 +144,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 +264,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 +344,10 @@ 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..3abbe58 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,7 +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; }
nitpick: add a space ^ between {} and (
> private:
> LONG _pos_x;
> LONG _pos_y;
> @@ -52,7 +53,7 @@ private:
> DWORD _height;
> DWORD _depth;
> bool _attached;
> -
> + bool _primary;
> friend class DesktopLayout;
> };
>
> @@ -74,10 +75,11 @@ 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);
nitpick: This line is pretty long.
Thanks,
Uri.
More information about the Spice-devel
mailing list