From 6b74ffb8ebf429ffbd3280b330d46134a7ff4d6c Mon Sep 17 00:00:00 2001 From: Arnon Gilboa Date: Wed, 16 Mar 2011 17:10:09 +0200 Subject: [PATCH] vdagent: remove dependency on qxl driver (rhbz#683166) -don't fail to start when no qxl driver installed -if qxls found use them, otherwise just use enumerated non-mirror devices -currently qxl/non-qxl multimon mix is not supported --- vdagent/desktop_layout.cpp | 104 +++++++++++++++++++++++++------------ vdagent/desktop_layout.h | 1 + 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/vdagent/desktop_layout.cpp b/vdagent/desktop_layout.cpp index 010d821..9bd1852 100644 --- a/vdagent/desktop_layout.cpp +++ b/vdagent/desktop_layout.cpp @@ -42,7 +42,7 @@ void DesktopLayout::get_displays() { DISPLAY_DEVICE dev_info; DEVMODE mode; - DWORD qxl_id; + DWORD display_id; DWORD dev_id = 0; LONG min_x = 0; LONG min_y = 0; @@ -51,37 +51,44 @@ void DesktopLayout::get_displays() bool attached; lock(); + if (!consistent_displays()) { + unlock(); + return; + } clean_displays(); ZeroMemory(&dev_info, sizeof(dev_info)); dev_info.cb = sizeof(dev_info); ZeroMemory(&mode, sizeof(mode)); mode.dmSize = sizeof(mode); while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) { - if (wcsstr(dev_info.DeviceString, L"QXL")) { - attached = !!(dev_info.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP); - EnumDisplaySettings(dev_info.DeviceName, ENUM_CURRENT_SETTINGS, &mode); - if (!get_qxl_device_id(dev_info.DeviceKey, &qxl_id)) { - vd_printf("get_qxl_device_id failed"); - break; - } - size_t size = _displays.size(); - if (qxl_id >= size) { - _displays.resize(qxl_id + 1); - for (size_t i = size; i < qxl_id; i++) { - _displays[i] = NULL; - } - } - _displays[qxl_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); + dev_id++; + if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) { + continue; + } + size_t size = _displays.size(); + if (!wcsstr(dev_info.DeviceString, L"QXL")) { + display_id = size; + } else if (!get_qxl_device_id(dev_info.DeviceKey, &display_id)) { + vd_printf("get_qxl_device_id failed %S", dev_info.DeviceKey); + break; + } + if (display_id >= size) { + _displays.resize(display_id + 1); + for (size_t i = size; i < display_id; i++) { + _displays[i] = NULL; } } - dev_id++; + 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++) { @@ -98,27 +105,33 @@ void DesktopLayout::set_displays() DISPLAY_DEVICE dev_info; DEVMODE dev_mode; DWORD dev_id = 0; - DWORD qxl_id = 0; + DWORD display_id = 0; int dev_sets = 0; lock(); + if (!consistent_displays()) { + unlock(); + return; + } ZeroMemory(&dev_info, sizeof(dev_info)); dev_info.cb = sizeof(dev_info); ZeroMemory(&dev_mode, sizeof(dev_mode)); dev_mode.dmSize = sizeof(dev_mode); - while (EnumDisplayDevices(NULL, dev_id++, &dev_info, 0)) { - if (!wcsstr(dev_info.DeviceString, L"QXL")) { + while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) { + dev_id++; + if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) { continue; } - if (!get_qxl_device_id(dev_info.DeviceKey, &qxl_id)) { - vd_printf("get_qxl_device_id failed"); + bool is_qxl = !!wcsstr(dev_info.DeviceString, L"QXL"); + if (is_qxl && !get_qxl_device_id(dev_info.DeviceKey, &display_id)) { + vd_printf("get_qxl_device_id failed %S", dev_info.DeviceKey); break; } - if (qxl_id >= _displays.size()) { - vd_printf("qxl_id %u out of range, #displays %u", qxl_id, _displays.size()); + if (display_id >= _displays.size()) { + vd_printf("display_id %u out of range, #displays %u", display_id, _displays.size()); break; } - if (!init_dev_mode(dev_info.DeviceName, &dev_mode, _displays.at(qxl_id), true)) { + if (!init_dev_mode(dev_info.DeviceName, &dev_mode, _displays.at(display_id), true)) { vd_printf("No suitable mode found for display %S", dev_info.DeviceName); break; } @@ -128,6 +141,9 @@ void DesktopLayout::set_displays() if (ret == DISP_CHANGE_SUCCESSFUL) { dev_sets++; } + if (!is_qxl) { + display_id++; + } } if (dev_sets) { ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); @@ -135,6 +151,30 @@ void DesktopLayout::set_displays() unlock(); } +bool DesktopLayout::consistent_displays() +{ + DISPLAY_DEVICE dev_info; + DWORD dev_id = 0; + int non_qxl_count = 0; + int qxl_count = 0; + + ZeroMemory(&dev_info, sizeof(dev_info)); + dev_info.cb = sizeof(dev_info); + while (EnumDisplayDevices(NULL, dev_id, &dev_info, 0)) { + dev_id++; + if (dev_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) { + continue; + } + if (wcsstr(dev_info.DeviceString, L"QXL")) { + qxl_count++; + } else { + non_qxl_count++; + } + } + vd_printf("#qxls %d #others %d", qxl_count, non_qxl_count); + return (!qxl_count || !non_qxl_count); +} + void DesktopLayout::clean_displays() { lock(); diff --git a/vdagent/desktop_layout.h b/vdagent/desktop_layout.h index f3294b5..caab84f 100644 --- a/vdagent/desktop_layout.h +++ b/vdagent/desktop_layout.h @@ -73,6 +73,7 @@ public: private: void clean_displays(); + 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);