[Spice-devel] [PATCH vdagent-win] vdagent: fix cursor position sync on multimon rhbz#757819
Arnon Gilboa
agilboa at redhat.com
Wed Feb 1 06:38:44 PST 2012
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? :/
>> 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