[Spice-devel] [RFC PATCH vdagent 02/16] Provide support for Windows 10 CCD API
Christophe Fergeau
cfergeau at redhat.com
Wed Jul 20 15:53:51 UTC 2016
On Mon, Jul 18, 2016 at 09:34:36AM +0300, Dmitry Fleytman wrote:
> diff --git a/vdagent/display_configuration.h b/vdagent/display_configuration.h
> new file mode 100644
> index 0000000..eeba1c2
> --- /dev/null
> +++ b/vdagent/display_configuration.h
> @@ -0,0 +1,192 @@
> +/*
> +Copyright (C) 2015 Red Hat, Inc.
> +
> +This program is free software; you can redistribute it and/or
> +modify it under the terms of the GNU General Public License as
> +published by the Free Software Foundation; either version 2 of
> +the License, or (at your option) any later version.
> +
> +This program is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with this program. If not, see <http://www.gnu.org/licenses/>.
> +*/
> +#pragma once
> +#include <sdkddkver.h>
> +#include <windows.h>
> +#include <d3dtypes.h>
> +#include "vdlog.h"
> +
> +#ifdef __MINGW32__
> +#include "d3dkmt.h"
> +#include "CCD.h"
> +#endif
> +
> +//Check for a reasonable SDK
> +#if (_WIN32_WINNT < _WIN32_WINNT_WINXP)
> +#error required Windows WDK not found
> +#endif
> +
> +//Windows 10 build only
> +#if (_WIN32_WINNT == _WIN32_WINNT_WIN10)
> +#include <d3dumddi.h>
> +#include <km/D3dkmthk.h>
> +#endif
> +
> +#include <spice/qxl_windows.h>
> +#include <spice/qxl_dev.h>
> +#include "desktop_layout.h"
> +#include "vdlog.h"
> +
> +typedef enum {
> + XPDM,
> + WDDM,
> + INVALID_DRIVER,
> +}DRIVER_TYPE;
> +
> +typedef enum {
> + MONITOR_DETACHED,
> + MONITOR_ATTACHED,
> +}MONITOR_STATE;
> +
> +typedef enum {
> + PATH_UPDATED,
> + PATH_CURRENT,
> +}PATH_STATE;
> +
> +#if (_WIN32_WINNT == _WIN32_WINNT_WIN10)
> +//Makes calls into the CCD API for getting/setting display settings on WDDM drivers
> +//Use is exclusive to wddm display config class
> +
> +typedef LONG(APIENTRY* PDISPLAYCONFIG_GETDEVICEINFO)(DISPLAYCONFIG_DEVICE_INFO_HEADER*);
> +typedef LONG(APIENTRY* PGETDISPLAYCONFIG_BUFFERSIZES)(UINT32, UINT32*, UINT32*);
> +typedef LONG(APIENTRY* PQUERYDISPLAYCONFIG)(UINT32, UINT32*, DISPLAYCONFIG_PATH_INFO*, UINT32*,
> + DISPLAYCONFIG_MODE_INFO*, DISPLAYCONFIG_TOPOLOGY_ID*);
> +typedef LONG(APIENTRY* PSETDISPLAYCONFIG)(UINT32, DISPLAYCONFIG_PATH_INFO*, UINT32,
> + DISPLAYCONFIG_MODE_INFO*, UINT32);
> +
> +class CCD {
> +protected:
> + CCD();
> + ~CCD();
> +
> + bool query_display_config();
> + bool set_display_config();
> + bool update_mode_position(LPCTSTR device_name, DEVMODE* dev_mode);
> + bool update_mode_size(LPCTSTR DeviceNmae, DEVMODE* dev_mode);
> + void update_detached_primary_state(LPCTSTR device_name, DISPLAYCONFIG_PATH_INFO * path_info);
> + bool set_path_state(LPCTSTR device_name, MONITOR_STATE state);
> + bool is_attached(LPCTSTR device_name);
> + bool is_active_path(DISPLAYCONFIG_PATH_INFO * path);
> + LONG error() { return _error; }
> +
> +private:
> + bool load_api();
> + bool get_config_buffers();
> + void free_config_buffers();
> + bool verify_primary_position();
> + bool is_device_path(LPCTSTR device_name, DISPLAYCONFIG_PATH_INFO* path);
> + DISPLAYCONFIG_MODE_INFO* get_active_mode(LPCTSTR device_name, bool return_on_error);
> + DISPLAYCONFIG_PATH_INFO* get_device_path(LPCTSTR device_name, bool bActive);
> + bool get_device_name_config(DISPLAYCONFIG_PATH_INFO* path, LPCTSTR dev_name);
> + void debug_print_config(const char* prefix = NULL);
> +
> +private:
> + //CCD API stuff
> + UINT32 _NumPathElements;
> + UINT32 _NumModeElements;
> + DISPLAYCONFIG_PATH_INFO* _pPathInfo;
> + DISPLAYCONFIG_MODE_INFO* _pModeInfo;
> +
> + //CCD API function pointers
> + PDISPLAYCONFIG_GETDEVICEINFO _pfnGetDeviceInfo;
> + PGETDISPLAYCONFIG_BUFFERSIZES _pfnGetDisplayConfigBufferSizes;
> + PQUERYDISPLAYCONFIG _pfnQueryDisplayConfig;
> + PSETDISPLAYCONFIG _pfnSetDisplayConfig;
> +
> + LONG _error;
> + bool _primary_detached;
> + PATH_STATE _path_state;
> + friend class WDDMInterface;
> +};
> +#endif
> +
> +class DisplayMode;
> +
> +//Class provides interface to get/set display configurations
> +class DisplayConfig {
> +public:
> + static DisplayConfig* create_config();
> + DisplayConfig();;
> + virtual ~DisplayConfig() {};
> +
> + virtual bool is_attached(DISPLAY_DEVICE* dev_info) = 0;
> + virtual bool custom_display_escape(LPCTSTR device, DEVMODE* mode) = 0;
> + virtual bool update_monitor_config(LPCTSTR device, DisplayMode* mode, DEVMODE* dev_mode) = 0;
> + virtual bool set_monitor_state(LPCTSTR device_name, DEVMODE* dev_mode, MONITOR_STATE state) = 0;
> + virtual LONG update_display_settings() = 0;
> + virtual bool update_dev_mode_position(LPCTSTR dev_name, DEVMODE* dev_mode, LONG x, LONG y) = 0;
> + DRIVER_TYPE type() { return _driver_type; };
> + void set_monitors_config(bool flag) { _send_monitors_config = flag; }
> + virtual void update_config_path() {};
> +
> +protected:
> + DRIVER_TYPE _driver_type;
> + bool _send_monitors_config;
> +};
> +
> +//DisplayConfig implementation for guest with XPDM graphics drivers
> +class XPDMInterface : public DisplayConfig {
> +public:
> + XPDMInterface() :DisplayConfig() { _driver_type = XPDM; };
> + ~XPDMInterface() {}
> + bool is_attached(DISPLAY_DEVICE* dev_info);;
> + bool custom_display_escape(LPCTSTR device_name, DEVMODE* dev_mode);
> + bool update_monitor_config(LPCTSTR device_name, DisplayMode* mode, DEVMODE* dev_mode);
> + bool set_monitor_state(LPCTSTR device_name, DEVMODE* dev_mode, MONITOR_STATE state);
> + LONG update_display_settings();
> + bool update_dev_mode_position(LPCTSTR device_name, DEVMODE * dev_mode, LONG x, LONG y);
> +
> +private:
> + bool find_best_mode(LPCTSTR Device, DEVMODE* dev_mode);
> +};
> +#if (_WIN32_WINNT == _WIN32_WINNT_WIN10)
> +//DisplayConfig implementation for guest with WDDM graphics drivers
> +class WDDMInterface : public DisplayConfig {
> +public:
> + WDDMInterface();
> + ~WDDMInterface();
> + bool is_attached(DISPLAY_DEVICE* dev_info);
> + bool set_monitor_state(LPCTSTR device_name, DEVMODE* dev_mode, MONITOR_STATE state);
> + LONG update_display_settings();
> + bool custom_display_escape(LPCTSTR device_name, DEVMODE* dev_mode);
> + bool update_monitor_config(LPCTSTR device_name, DisplayMode* mode, DEVMODE* dev_mode);
> + bool update_dev_mode_position(LPCTSTR device_name, DEVMODE * dev_mode, LONG x, LONG y);
> + void update_config_path();
> +
> +private:
> + bool init_d3d_api();
> + D3DKMT_HANDLE adapter_handle(LPCTSTR device_name);
> + D3DKMT_HANDLE handle_from_DC(LPCTSTR adapter_name);
> + D3DKMT_HANDLE handle_from_device_name(LPCTSTR adapter_name);
> + D3DKMT_HANDLE handle_from_GDI_name(LPCTSTR adapter_name);
> +
> + void close_adapter(D3DKMT_HANDLE handle);
> + bool escape(LPCTSTR device_name, void* data, UINT sizeData);
> +
> +private:
> + //GDI Function pointers
> + PFND3DKMT_OPENADAPTERFROMHDC _pfnOpen_adapter_hdc;
> + PFND3DKMT_CLOSEADAPTER _pfnClose_adapter;
> + PFND3DKMT_ESCAPE _pfnEscape;
> + PFND3DKMT_OPENADAPTERFROMDEVICENAME _pfnOpen_adapter_device_name;
> + PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME _pfnOpen_adapter_gdi_name;
> +
> + //object handles the CCD API
> + CCD _ccd;
> +};
> +#endif
> +typedef class DisplayConfig DISPLAY_CONFIG;
My understanding from this file is that there is a generic DisplayConfig
interface, a WDDMInterface implementation for Win10, and a XPDMInterface
implementation which will probably correspond to !Win10 agent?
It seems the XPDMInterface implementation is absent. However, if you
introduce DisplayConfig+XPDMInterface in the existing code (ie switch
the existing code to DisplayConfig _without any functional change_), and
then introduce the Win10 code, this will make this whole commit look
less like a huge codedump (and will make it easier to review).
Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20160720/8f240c35/attachment.sig>
More information about the Spice-devel
mailing list