> > From: Sandy Stutsman <sstutsma@xxxxxxxxxx> > > --- > Spice.props | 38 ++ > vdagent.sln | 94 ++-- > vdagent/CCD.h | 259 +++++++++++ > vdagent/D3Dkmt.h | 134 ++++++ > vdagent/desktop_layout.cpp | 152 ++----- > vdagent/desktop_layout.h | 9 +- > vdagent/display_configuration.cpp | 889 > ++++++++++++++++++++++++++++++++++++++ > vdagent/display_configuration.h | 192 ++++++++ > vdagent/vdagent.vcxproj | 380 ++++++++++++++++ > vdservice/vdservice.vcxproj | 197 +++++++++ > 10 files changed, 2185 insertions(+), 159 deletions(-) > create mode 100644 Spice.props > create mode 100644 vdagent/CCD.h > create mode 100644 vdagent/D3Dkmt.h > create mode 100644 vdagent/display_configuration.cpp > create mode 100644 vdagent/display_configuration.h > create mode 100644 vdagent/vdagent.vcxproj > create mode 100644 vdservice/vdservice.vcxproj > > diff --git a/Spice.props b/Spice.props > new file mode 100644 > index 0000000..217bfc7 > --- /dev/null > +++ b/Spice.props > @@ -0,0 +1,38 @@ > +<?xml version="1.0" encoding="utf-8"?> > +<Project ToolsVersion="4.0" > xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> > + <ImportGroup Label="PropertySheets" /> > + <PropertyGroup Label="UserMacros"> > + > <SPICE_PROTOCOL_DIR>D:\SANDBOX\Master\spice-protocol</SPICE_PROTOCOL_DIR> > + <SPICE_LIBS>D:\Sandbox\WSpice\</SPICE_LIBS> > + Can't we use relative directories here? > <SPICE_LIB_LIST>cximage.lib;jasper.lib;jbig.lib;jpeg.lib;libdcr.lib;mng.lib;png.lib;tiff.lib;zlib.lib</SPICE_LIB_LIST> > + > <SPICE_DEBUG_LIB_LIST>cximage.lib;jasper.lib;jbig.lib;jpeg.lib;libdcr.lib;mng.lib;png.lib;tiff.lib;zlib.lib</SPICE_DEBUG_LIB_LIST> > + <SPICE_LIBS_DIR>$(SPICE_LIBS)\$(Platform)\Release</SPICE_LIBS_DIR> > + > <SPICE_DEBUG_LIBS_DIR>$(SPICE_LIBS)\$(Platform)\Debug</SPICE_DEBUG_LIBS_DIR> > + </PropertyGroup> > + <PropertyGroup /> > + <ItemDefinitionGroup /> > + <ItemGroup> > + <BuildMacro Include="SPICE_PROTOCOL_DIR"> > + <Value>$(SPICE_PROTOCOL_DIR)</Value> > + <EnvironmentVariable>true</EnvironmentVariable> > + </BuildMacro> > + <BuildMacro Include="SPICE_LIBS"> > + <Value>$(SPICE_LIBS)</Value> > + <EnvironmentVariable>true</EnvironmentVariable> > + </BuildMacro> > + <BuildMacro Include="SPICE_LIB_LIST"> > + <Value>$(SPICE_LIB_LIST)</Value> > + <EnvironmentVariable>true</EnvironmentVariable> > + </BuildMacro> > + <BuildMacro Include="SPICE_DEBUG_LIB_LIST"> > + <Value>$(SPICE_DEBUG_LIB_LIST)</Value> > + <EnvironmentVariable>true</EnvironmentVariable> > + </BuildMacro> > + <BuildMacro Include="SPICE_LIBS_DIR"> > + <Value>$(SPICE_LIBS_DIR)</Value> > + </BuildMacro> > + <BuildMacro Include="SPICE_DEBUG_LIBS_DIR"> > + <Value>$(SPICE_DEBUG_LIBS_DIR)</Value> > + </BuildMacro> > + </ItemGroup> > +</Project> > \ No newline at end of file > diff --git a/vdagent.sln b/vdagent.sln > index 2622f2e..1c29664 100644 > --- a/vdagent.sln > +++ b/vdagent.sln > @@ -1,36 +1,58 @@ > - > -Microsoft Visual Studio Solution File, Format Version 10.00 > -# Visual Studio 2008 > -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdagent", > "vdagent\vdagent.vcproj", "{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}" > -EndProject > -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdservice", > "vdservice\vdservice.vcproj", "{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}" > -EndProject > -Global > - GlobalSection(SolutionConfigurationPlatforms) = preSolution > - Debug|Win32 = Debug|Win32 > - Debug|x64 = Debug|x64 > - Release|Win32 = Release|Win32 > - Release|x64 = Release|x64 > - EndGlobalSection > - GlobalSection(ProjectConfigurationPlatforms) = postSolution > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|Win32.ActiveCfg = Debug|Win32 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|Win32.Build.0 = Debug|Win32 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|x64.ActiveCfg = Debug|x64 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|x64.Build.0 = Debug|x64 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|Win32.ActiveCfg = > Release|Win32 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|Win32.Build.0 = > Release|Win32 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|x64.ActiveCfg = Release|x64 > - {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|x64.Build.0 = Release|x64 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|Win32.ActiveCfg = Debug|Win32 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|Win32.Build.0 = Debug|Win32 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|x64.ActiveCfg = Debug|x64 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|x64.Build.0 = Debug|x64 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.ActiveCfg = > Release|Win32 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.Build.0 = > Release|Win32 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.ActiveCfg = Release|x64 > - {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.Build.0 = Release|x64 > - EndGlobalSection > - GlobalSection(SolutionProperties) = preSolution > - HideSolutionNode = FALSE > - EndGlobalSection > -EndGlobal > + > +Microsoft Visual Studio Solution File, Format Version 12.00 > +# Visual Studio 14 > +VisualStudioVersion = 14.0.23107.0 > +MinimumVisualStudioVersion = 10.0.40219.1 > +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdagent", > "vdagent\vdagent.vcxproj", "{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}" > +EndProject > +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdservice", > "vdservice\vdservice.vcxproj", "{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}" > +EndProject > +Global > + GlobalSection(SolutionConfigurationPlatforms) = preSolution > + Debug|Win32 = Debug|Win32 > + Debug|x64 = Debug|x64 > + Release|Win32 = Release|Win32 > + Release|x64 = Release|x64 > + Win10 Debug|Win32 = Win10 Debug|Win32 > + Win10 Debug|x64 = Win10 Debug|x64 > + Win10 Release|Win32 = Win10 Release|Win32 > + Win10 Release|x64 = Win10 Release|x64 > + EndGlobalSection > + GlobalSection(ProjectConfigurationPlatforms) = postSolution > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|Win32.ActiveCfg = Debug|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|Win32.Build.0 = Debug|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|x64.ActiveCfg = Debug|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|x64.Build.0 = Debug|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|Win32.ActiveCfg = > Release|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|Win32.Build.0 = > Release|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|x64.ActiveCfg = Release|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|x64.Build.0 = Release|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Debug|Win32.ActiveCfg = Win10 > Debug|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Debug|Win32.Build.0 = Win10 > Debug|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Debug|x64.ActiveCfg = Win10 > Debug|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Debug|x64.Build.0 = Win10 > Debug|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Release|Win32.ActiveCfg = > Win10 Release|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Release|Win32.Build.0 = Win10 > Release|Win32 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Release|x64.ActiveCfg = Win10 > Release|x64 > + {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Win10 Release|x64.Build.0 = Win10 > Release|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|Win32.ActiveCfg = Debug|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|Win32.Build.0 = Debug|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|x64.ActiveCfg = Debug|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|x64.Build.0 = Debug|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.ActiveCfg = > Release|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.Build.0 = > Release|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.ActiveCfg = Release|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.Build.0 = Release|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Debug|Win32.ActiveCfg = > Debug|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Debug|Win32.Build.0 = > Debug|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Debug|x64.ActiveCfg = > Debug|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Debug|x64.Build.0 = Debug|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Release|Win32.ActiveCfg = > Release|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Release|Win32.Build.0 = > Release|Win32 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Release|x64.ActiveCfg = > Release|x64 > + {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Win10 Release|x64.Build.0 = > Release|x64 > + EndGlobalSection > + GlobalSection(SolutionProperties) = preSolution > + HideSolutionNode = FALSE > + EndGlobalSection > +EndGlobal > diff --git a/vdagent/CCD.h b/vdagent/CCD.h > new file mode 100644 > index 0000000..a457fc1 > --- /dev/null > +++ b/vdagent/CCD.h > @@ -0,0 +1,259 @@ > +/* > +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/>. > +*/ > + > +//This file provides defines and structures required by Windows CCD API and > +//not currently supplied by the MINGW32 header files. > +#pragma once > + > +// > +// Definitions used by QueryDisplayConfig. > +// > + > +#if (_WIN32_WINNT < 0X0601) > +#define QDC_ALL_PATHS 0x00000001 > +#define QDC_ONLY_ACTIVE_PATHS 0x00000002 > +#define QDC_DATABASE_CURRENT 0x00000004 > +#define QDC_VIRTUAL_MODE_AWARE 0x00000010 > + Are we sure we can do this freely? These definitions came from Microsoft. Either website or some header I don't think we can copy and past and change licensing. > +// > +// Definitions used by SetDisplayConfig. > +// > + > +#define SDC_TOPOLOGY_INTERNAL 0x00000001 > +#define SDC_TOPOLOGY_CLONE 0x00000002 > +#define SDC_TOPOLOGY_EXTEND 0x00000004 > +#define SDC_TOPOLOGY_EXTERNAL 0x00000008 > +#define SDC_TOPOLOGY_SUPPLIED 0x00000010 > +#define SDC_USE_DATABASE_CURRENT (SDC_TOPOLOGY_INTERNAL | > SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL) > + > +#define SDC_USE_SUPPLIED_DISPLAY_CONFIG 0x00000020 > +#define SDC_VALIDATE 0x00000040 > +#define SDC_APPLY 0x00000080 > +#define SDC_NO_OPTIMIZATION 0x00000100 > +#define SDC_SAVE_TO_DATABASE 0x00000200 > +#define SDC_ALLOW_CHANGES 0x00000400 > +#define SDC_PATH_PERSIST_IF_REQUIRED 0x00000800 > +#define SDC_FORCE_MODE_ENUMERATION 0x00001000 > +#define SDC_ALLOW_PATH_ORDER_CHANGES 0x00002000 > +#define SDC_VIRTUAL_MODE_AWARE 0x00008000 > + > +#define DISPLAYCONFIG_PATH_ACTIVE 0x00000001 > +#define DISPLAYCONFIG_PATH_MODE_IDX_INVALID 0xffffffff > + > +typedef enum { > + DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1, > + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2, > + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3, > + DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4, > + DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5, > + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6, > + DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION = 7, > + DISPLAYCONFIG_DEVICE_INFO_SET_SUPPORT_VIRTUAL_RESOLUTION = 8, > + DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_DEVICE_INFO_TYPE; > + > + > +typedef enum { > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = -1, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST = 15, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000, > + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY; > + > + > +typedef enum { > + DISPLAYCONFIG_ROTATION_IDENTITY = 1, > + DISPLAYCONFIG_ROTATION_ROTATE90 = 2, > + DISPLAYCONFIG_ROTATION_ROTATE180 = 3, > + DISPLAYCONFIG_ROTATION_ROTATE270 = 4, > + DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_ROTATION; > + > +typedef enum { > + DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0, > + DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1, > + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2, > + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = > DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED, > + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3, > + DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_SCANLINE_ORDERING; > + > + > +typedef enum { > + DISPLAYCONFIG_SCALING_IDENTITY = 1, > + DISPLAYCONFIG_SCALING_CENTERED = 2, > + DISPLAYCONFIG_SCALING_STRETCHED = 3, > + DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4, > + DISPLAYCONFIG_SCALING_CUSTOM = 5, > + DISPLAYCONFIG_SCALING_PREFERRED = 128, > + DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_SCALING; > + > + > +typedef enum { > + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1, > + DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2, > + DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE = 3, > + DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_MODE_INFO_TYPE; > + > + > +typedef enum { > + DISPLAYCONFIG_PIXELFORMAT_8BPP = 1, > + DISPLAYCONFIG_PIXELFORMAT_16BPP = 2, > + DISPLAYCONFIG_PIXELFORMAT_24BPP = 3, > + DISPLAYCONFIG_PIXELFORMAT_32BPP = 4, > + DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5, > + DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff > +} DISPLAYCONFIG_PIXELFORMAT; > + > +typedef enum { > + DISPLAYCONFIG_TOPOLOGY_INTERNAL = 0x00000001, > + DISPLAYCONFIG_TOPOLOGY_CLONE = 0x00000002, > + DISPLAYCONFIG_TOPOLOGY_EXTEND = 0x00000004, > + DISPLAYCONFIG_TOPOLOGY_EXTERNAL = 0x00000008, > + DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32 = 0xFFFFFFFF > +} DISPLAYCONFIG_TOPOLOGY_ID; > + > + > +typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER { > + DISPLAYCONFIG_DEVICE_INFO_TYPE type; > + UINT32 size; > + LUID adapterId; > + UINT32 id; > +} DISPLAYCONFIG_DEVICE_INFO_HEADER; > + > +typedef struct DISPLAYCONFIG_SOURCE_DEVICE_NAME { > + DISPLAYCONFIG_DEVICE_INFO_HEADER header; > + WCHAR > viewGdiDeviceName[CCHDEVICENAME]; > +} DISPLAYCONFIG_SOURCE_DEVICE_NAME; > + > +typedef struct DISPLAYCONFIG_DESKTOP_IMAGE_INFO { > + POINTL PathSourceSize; > + RECTL DesktopImageRegion; > + RECTL DesktopImageClip; > +} DISPLAYCONFIG_DESKTOP_IMAGE_INFO; > + > +typedef struct DISPLAYCONFIG_RATIONAL { > + UINT32 Numerator; > + UINT32 Denominator; > +} DISPLAYCONFIG_RATIONAL; > + > +typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO { > + LUID adapterId; > + UINT32 id; > + union { > + UINT32 modeInfoIdx; > + struct { > + UINT32 cloneGroupId : 16; > + UINT32 sourceModeInfoIdx : 16; > + } DUMMYSTRUCTNAME; > + } DUMMYUNIONNAME; > + > + UINT32 statusFlags; > +} DISPLAYCONFIG_PATH_SOURCE_INFO; > + > + > +typedef struct DISPLAYCONFIG_PATH_TARGET_INFO { > + LUID adapterId; > + UINT32 id; > + union { > + UINT32 modeInfoIdx; > + struct { > + UINT32 desktopModeInfoIdx : 16; > + UINT32 targetModeInfoIdx : 16; > + } DUMMYSTRUCTNAME; > + } DUMMYUNIONNAME; > + DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology; > + DISPLAYCONFIG_ROTATION rotation; > + DISPLAYCONFIG_SCALING scaling; > + DISPLAYCONFIG_RATIONAL refreshRate; > + DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering; > + BOOL targetAvailable; > + UINT32 statusFlags; > +} DISPLAYCONFIG_PATH_TARGET_INFO; > + > +typedef struct DISPLAYCONFIG_PATH_INFO { > + DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo; > + DISPLAYCONFIG_PATH_TARGET_INFO targetInfo; > + UINT32 flags; > +} DISPLAYCONFIG_PATH_INFO; > + > +typedef struct DISPLAYCONFIG_2DREGION { > + UINT32 cx; > + UINT32 cy; > +} DISPLAYCONFIG_2DREGION; > + > +typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO { > + UINT64 pixelRate; > + DISPLAYCONFIG_RATIONAL hSyncFreq; > + DISPLAYCONFIG_RATIONAL vSyncFreq; > + DISPLAYCONFIG_2DREGION activeSize; > + DISPLAYCONFIG_2DREGION totalSize; > + > + union { > + struct { > + UINT32 videoStandard : 16; > + > + UINT32 vSyncFreqDivider : 6; > + > + UINT32 reserved : 10; > + } AdditionalSignalInfo; > + > + UINT32 videoStandard; > + } DUMMYUNIONNAME; > + > + DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering; > +} DISPLAYCONFIG_VIDEO_SIGNAL_INFO; > + > +typedef struct DISPLAYCONFIG_TARGET_MODE { > + DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo; > +} DISPLAYCONFIG_TARGET_MODE; > + > +typedef struct DISPLAYCONFIG_SOURCE_MODE { > + UINT32 width; > + UINT32 height; > + DISPLAYCONFIG_PIXELFORMAT pixelFormat; > + POINTL position; > +} DISPLAYCONFIG_SOURCE_MODE; > + > +typedef struct DISPLAYCONFIG_MODE_INFO { > + DISPLAYCONFIG_MODE_INFO_TYPE infoType; > + UINT32 id; > + LUID adapterId; > + union { > + DISPLAYCONFIG_TARGET_MODE targetMode; > + DISPLAYCONFIG_SOURCE_MODE sourceMode; > + DISPLAYCONFIG_DESKTOP_IMAGE_INFO desktopImageInfo; > + } DUMMYUNIONNAME; > +} DISPLAYCONFIG_MODE_INFO; > + > +#endif > \ No newline at end of file > diff --git a/vdagent/D3Dkmt.h b/vdagent/D3Dkmt.h > new file mode 100644 > index 0000000..81530fb > --- /dev/null > +++ b/vdagent/D3Dkmt.h > @@ -0,0 +1,134 @@ > + > +/* > +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/>. > +*/ > + > +//File provides definitions and structures for the D3D KMT interface calls > +//make by WDDM vd agent interface > + > +#pragma once > +#include <winnt.h> > +typedef UINT D3DKMT_HANDLE; > +typedef UINT D3DDDI_VIDEO_PRESENT_SOURCE_ID; > + > +typedef struct _D3DKMT_OPENADAPTERFROMHDC { > + HDC hDc; > + D3DKMT_HANDLE hAdapter; > + LUID AdapterLuid; > + D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId; > +} D3DKMT_OPENADAPTERFROMHDC; > + > +typedef struct _D3DKMT_CLOSEADAPTER { > + D3DKMT_HANDLE hAdapter; > +} D3DKMT_CLOSEADAPTER; > + > +typedef enum _D3DKMT_ESCAPETYPE { > + D3DKMT_ESCAPE_DRIVERPRIVATE = 0, > + D3DKMT_ESCAPE_VIDMM = 1, > + D3DKMT_ESCAPE_TDRDBGCTRL = 2, > + D3DKMT_ESCAPE_VIDSCH = 3, > + D3DKMT_ESCAPE_DEVICE = 4, > + D3DKMT_ESCAPE_DMM = 5, > + D3DKMT_ESCAPE_DEBUG_SNAPSHOT = 6, > + D3DKMT_ESCAPE_SETDRIVERUPDATESTATUS = 7, > + D3DKMT_ESCAPE_DRT_TEST = 8, > +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WIN8) > + D3DKMT_ESCAPE_DIAGNOSTICS = 9, > + D3DKMT_ESCAPE_OUTPUTDUPL_SNAPSHOT = 10, > + D3DKMT_ESCAPE_OUTPUTDUPL_DIAGNOSTICS = 11, > + D3DKMT_ESCAPE_BDD_PNP = 12, > + D3DKMT_ESCAPE_BDD_FALLBACK = 13, > + D3DKMT_ESCAPE_ACTIVATE_SPECIFIC_DIAG = 14, > + D3DKMT_ESCAPE_MODES_PRUNED_OUT = 15, > + D3DKMT_ESCAPE_WHQL_INFO = 16, > + D3DKMT_ESCAPE_BRIGHTNESS = 17, > + D3DKMT_ESCAPE_EDID_CACHE = 18, > + D3DKMT_ESCAPE_GENERIC_ADAPTER_DIAG_INFO = 19, > +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM1_3) > + D3DKMT_ESCAPE_MIRACAST_DISPLAY_REQUEST = 20, > + D3DKMT_ESCAPE_HISTORY_BUFFER_STATUS = 21, > + D3DKMT_ESCAPE_MIRACAST_ADAPTER_DIAG_INFO = 23, > +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_0) > + D3DKMT_ESCAPE_FORCE_BDDFALLBACK_HEADLESS = 24, > + D3DKMT_ESCAPE_REQUEST_MACHINE_CRASH = 25, > +#endif > +#endif > + > + D3DKMT_ESCAPE_WIN32K_START = 1024, > + D3DKMT_ESCAPE_WIN32K_HIP_DEVICE_INFO = 1024, > + D3DKMT_ESCAPE_WIN32K_QUERY_CD_ROTATION_BLOCK = 1025, > +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM1_3) > + D3DKMT_ESCAPE_WIN32K_DPI_INFO = 1026, > + D3DKMT_ESCAPE_WIN32K_PRESENTER_VIEW_INFO = 1027, > + D3DKMT_ESCAPE_WIN32K_SYSTEM_DPI = 1028, > +#if (DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM2_0) > + D3DKMT_ESCAPE_WIN32K_BDD_FALLBACK = 1029, > + D3DKMT_ESCAPE_WIN32K_DDA_TEST_CTL = 1030, > + D3DKMT_ESCAPE_WIN32K_USER_DETECTED_BLACK_SCREEN = 1031, > +#endif // DXGKDDI_INTERFACE_VERSION_WDDM2_0 > +#endif // DXGKDDI_INTERFACE_VERSION_WDDM1_3 > +#endif // DXGKDDI_INTERFACE_VERSION_WIN8 > +} D3DKMT_ESCAPETYPE; > + > + > +typedef struct _D3DDDI_ESCAPEFLAGS { > + union { > + struct { > + UINT HardwareAccess : 1; > +#if ((DXGKDDI_INTERFACE_VERSION >= DXGKDDI_INTERFACE_VERSION_WDDM1_3) || \ > + (D3D_UMD_INTERFACE_VERSION >= D3D_UMD_INTERFACE_VERSION_WDDM1_3)) > + UINT DeviceStatusQuery : 1; > + UINT ChangeFrameLatency : 1; > + UINT Reserved : 29; > +#else > + UINT Reserved : 31; > +#endif // WDDM1_3 > + }; > + UINT Value; > + }; > +} D3DDDI_ESCAPEFLAGS; > + > +typedef struct _D3DKMT_ESCAPE { > + D3DKMT_HANDLE hAdapter; > + D3DKMT_HANDLE hDevice; > + D3DKMT_ESCAPETYPE Type; > + D3DDDI_ESCAPEFLAGS Flags; > + VOID* pPrivateDriverData; > + UINT PrivateDriverDataSize; > + D3DKMT_HANDLE hContext; > +} D3DKMT_ESCAPE; > + > + > +typedef struct _D3DKMT_OPENADAPTERFROMDEVICENAME { > + PCWSTR pDeviceName; > + D3DKMT_HANDLE hAdapter; > + LUID AdapterLuid; > +} D3DKMT_OPENADAPTERFROMDEVICENAME; > + > +typedef UINT D3DDDI_VIDEO_PRESENT_SOURCE_ID; > + > +typedef struct _D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME { > + WCHAR DeviceName[32]; > + D3DKMT_HANDLE hAdapter; > + LUID AdapterLuid; > + D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId; > +} D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME; > + > +typedef NTSTATUS(APIENTRY* PFND3DKMT_ESCAPE)(CONST D3DKMT_ESCAPE*); > +typedef NTSTATUS(APIENTRY* > PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME*); > +typedef NTSTATUS(APIENTRY* > PFND3DKMT_OPENADAPTERFROMDEVICENAME)(D3DKMT_OPENADAPTERFROMDEVICENAME*); > +typedef NTSTATUS(APIENTRY* PFND3DKMT_CLOSEADAPTER)(D3DKMT_CLOSEADAPTER*); > +typedef NTSTATUS(APIENTRY* > PFND3DKMT_OPENADAPTERFROMHDC)(D3DKMT_OPENADAPTERFROMHDC*); > \ No newline at end of file > diff --git a/vdagent/desktop_layout.cpp b/vdagent/desktop_layout.cpp > index a7666ca..7aff7e7 100644 > --- a/vdagent/desktop_layout.cpp > +++ b/vdagent/desktop_layout.cpp > @@ -18,8 +18,8 @@ > #include <spice/qxl_windows.h> > #include <spice/qxl_dev.h> > #include "desktop_layout.h" > +#include "display_configuration.h" > #include "vdlog.h" > - > #ifdef __MINGW32__ > using std::min; > using std::max; > @@ -35,15 +35,19 @@ void DisplayMode::set_res(DWORD width, DWORD height, > DWORD depth) > DesktopLayout::DesktopLayout() > : _total_width (0) > , _total_height (0) > - , _send_monitors_position(false) > + , _display_config(NULL) > { > MUTEX_INIT(_mutex); > + _display_config = DISPLAY_CONFIG::create_config(); > get_displays(); > } > > DesktopLayout::~DesktopLayout() > { > clean_displays(); > + if (_display_config){ > + delete _display_config; > + } > } > > void DesktopLayout::get_displays() > @@ -59,6 +63,7 @@ void DesktopLayout::get_displays() > unlock(); > return; > } > + _display_config->update_config_path(); > clean_displays(); > ZeroMemory(&dev_info, sizeof(dev_info)); > dev_info.cb = sizeof(dev_info); > @@ -82,12 +87,13 @@ void DesktopLayout::get_displays() > _displays[i] = NULL; > } > } > - attached = !!(dev_info.StateFlags & > DISPLAY_DEVICE_ATTACHED_TO_DESKTOP); > + attached = _display_config->is_attached(&dev_info); > + > 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); > - update_monitor_config(dev_info.DeviceName, _displays[display_id]); > + _display_config->update_monitor_config(dev_info.DeviceName, > _displays[display_id], &mode); > } > normalize_displays_pos(); > unlock(); > @@ -121,6 +127,7 @@ void DesktopLayout::set_displays() > unlock(); > return; > } > + _display_config->update_config_path(); > ZeroMemory(&dev_info, sizeof(dev_info)); > dev_info.cb = sizeof(dev_info); > ZeroMemory(&dev_mode, sizeof(dev_mode)); > @@ -146,28 +153,32 @@ void DesktopLayout::set_displays() > break; > } > DisplayMode * mode(_displays.at(display_id)); > - if (!init_dev_mode(dev_info.DeviceName, &dev_mode, mode, normal_x, > normal_y, true)) { > + if (!init_dev_mode(dev_info.DeviceName, &dev_mode, mode)) { > vd_printf("No suitable mode found for display %S", > dev_info.DeviceName); > break; > } > vd_printf("Set display mode %lux%lu", dev_mode.dmPelsWidth, > dev_mode.dmPelsHeight); > - LONG ret = ChangeDisplaySettingsEx(dev_info.DeviceName, &dev_mode, > NULL, > - CDS_UPDATEREGISTRY | CDS_NORESET, > NULL); > - if (ret == DISP_CHANGE_SUCCESSFUL) { > + if(_display_config->update_dev_mode_position(dev_info.DeviceName, > &dev_mode, > + mode->_pos_x - > normal_x, > + mode->_pos_y - > normal_y)) { > dev_sets++; > - update_monitor_config(dev_info.DeviceName, mode); > + _display_config->update_monitor_config(dev_info.DeviceName, > mode, &dev_mode); > } > if (!is_qxl) { > display_id++; > } > } > if (dev_sets) { > - ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); > + _display_config->update_display_settings(); > normalize_displays_pos(); > } > unlock(); > } > > +void DesktopLayout::set_position_configurable(bool flag) { > + _display_config->set_monitors_config(flag); > +} > + > // 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() > @@ -265,125 +276,30 @@ bool DesktopLayout::get_qxl_device_id(WCHAR* > device_key, DWORD* device_id) > return key_found; > } > > -bool DesktopLayout::init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, > DisplayMode* mode, > - LONG normal_x, LONG normal_y, bool > set_pos) > +bool DesktopLayout::init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, > DisplayMode* mode) > { > - DWORD closest_diff = -1; > - DWORD best = -1; > - QXLEscapeSetCustomDisplay custom; > - HDC hdc = NULL; > - LONG ret; > - > ZeroMemory(dev_mode, sizeof(DEVMODE)); > dev_mode->dmSize = sizeof(DEVMODE); > - if (!mode || !mode->_attached) { > - //Detach monitor > - dev_mode->dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION; > + > + //Update monitor state > + MONITOR_STATE monitor_state = (!mode || !mode->_attached)? > MONITOR_DETACHED : MONITOR_ATTACHED; > + _display_config->set_monitor_state(dev_name, dev_mode, monitor_state); > + if (monitor_state == MONITOR_DETACHED) { > return true; > } > > - hdc = CreateDC(dev_name, NULL, NULL, NULL); > - if (!hdc) { > - // for some reason, windows want those 3 flags to enable monitor > - dev_mode->dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION; > - dev_mode->dmPelsWidth = mode->_width; > - dev_mode->dmPelsHeight = mode->_height; > - ret = ChangeDisplaySettingsEx(dev_name, dev_mode, NULL, > CDS_UPDATEREGISTRY, NULL); > - if (ret == DISP_CHANGE_BADMODE) { > - // custom resolution might not be set yet, use known resolution > - // FIXME: this causes client temporary resize... a > - // solution would involve passing custom resolution before > - // driver initialization, perhaps through registry > - dev_mode->dmPelsWidth = 640; > - dev_mode->dmPelsHeight = 480; > - ret = ChangeDisplaySettingsEx(dev_name, dev_mode, NULL, > CDS_UPDATEREGISTRY, NULL); > - } > - > - vd_printf("attach %ld", ret); > - hdc = CreateDC(dev_name, NULL, NULL, NULL); > - } > - > - if (!hdc) { > - vd_printf("failed to create DC"); > + // Update custom resolution > + dev_mode->dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION; > + dev_mode->dmPelsWidth = mode->_width; > + dev_mode->dmPelsHeight = mode->_height; > + dev_mode->dmBitsPerPel = mode->_depth; > + if (!_display_config->custom_display_escape(dev_name, dev_mode)) > return false; > - } else { > - // Update custom resolution > - custom.xres = mode->_width; > - custom.yres = mode->_height; > - custom.bpp = mode->_depth; > - > - int err = ExtEscape(hdc, QXL_ESCAPE_SET_CUSTOM_DISPLAY, > - sizeof(QXLEscapeSetCustomDisplay), > (LPCSTR)&custom, 0, NULL); > - if (err <= 0) { > - vd_printf("can't set custom display, perhaps an old driver"); > - } > - DeleteDC(hdc); > - } > - > - // force refresh mode table > - DEVMODE tempDevMode; > - ZeroMemory(&tempDevMode, sizeof (tempDevMode)); > - tempDevMode.dmSize = sizeof(DEVMODE); > - EnumDisplaySettings(dev_name, 0xffffff, &tempDevMode); > - > - //Find the closest size which will fit within the monitor > - for (DWORD i = 0; EnumDisplaySettings(dev_name, i, dev_mode); i++) { > - if (dev_mode->dmPelsWidth > mode->_width || > - dev_mode->dmPelsHeight > mode->_height || > - dev_mode->dmBitsPerPel != mode->_depth) { > - continue; > - } > - DWORD wdiff = mode->_width - dev_mode->dmPelsWidth; > - DWORD hdiff = mode->_height - dev_mode->dmPelsHeight; > - DWORD diff = wdiff * wdiff + hdiff * hdiff; > - if (diff < closest_diff) { > - closest_diff = diff; > - best = i; > - } > - } > - if (best == (DWORD)-1 || !EnumDisplaySettings(dev_name, best, dev_mode)) > { > - return false; > - } > - dev_mode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; > - if (set_pos) { > - //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; > - } > > // update current DisplayMode (so mouse scaling works properly) > mode->_width = dev_mode->dmPelsWidth; > mode->_height = dev_mode->dmPelsHeight; > - > return true; > -} > - > -bool DesktopLayout::update_monitor_config(LPCTSTR dev_name, DisplayMode* > mode) > -{ > - QXLHead monitor_config; > > - if (!mode || !mode->get_attached()) > - return false; > - > - //Don't configure monitors unless the client supports it > - if(!_send_monitors_position) return FALSE; > - > - HDC hdc = CreateDC(dev_name, NULL, NULL, NULL); > - > - memset(&monitor_config, 0, sizeof(monitor_config)); > - monitor_config.x = mode->_pos_x; > - monitor_config.y = mode->_pos_y; > - monitor_config.width = mode->_width; > - monitor_config.height = mode->_height; > - > - int err = ExtEscape(hdc, QXL_ESCAPE_MONITOR_CONFIG, > - sizeof(QXLHead), (LPCSTR) &monitor_config, 0, NULL); > - > - if (err < 0){ > - vd_printf("can't update monitor config, may have an older driver"); > - } > - > - DeleteDC(hdc); > - return (err >= 0); > } > + > diff --git a/vdagent/desktop_layout.h b/vdagent/desktop_layout.h > index ece3946..fd6af76 100644 > --- a/vdagent/desktop_layout.h > +++ b/vdagent/desktop_layout.h > @@ -60,6 +60,7 @@ private: > }; > > typedef std::vector<DisplayMode*> Displays; > +class DisplayConfig; > > class DesktopLayout { > public: > @@ -73,23 +74,21 @@ public: > size_t get_display_count() { return _displays.size();} > DWORD get_total_width() { return _total_width;} > DWORD get_total_height() { return _total_height;} > - void set_position_configurable(bool flag) { _send_monitors_position = > flag; } > + void set_position_configurable(bool flag); > private: > void clean_displays(); > void normalize_displays_pos(); > DisplayMode * get_primary_display(); > - bool update_monitor_config(LPCTSTR dev_name, DisplayMode* mode); > + bool init_dev_mode(LPCTSTR dev_name, DEVMODE* dev_mode, DisplayMode* > mode); > 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, > - LONG normal_x, LONG normal_y, bool set_pos); > private: > mutex_t _mutex; > Displays _displays; > DWORD _total_width; > DWORD _total_height; > - bool _send_monitors_position; > + DisplayConfig* _display_config; > }; > > #endif > diff --git a/vdagent/display_configuration.cpp > b/vdagent/display_configuration.cpp > new file mode 100644 > index 0000000..19641e9 > --- /dev/null > +++ b/vdagent/display_configuration.cpp > @@ -0,0 +1,889 @@ > +/* > +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/>. > +*/ > + > +#include "display_configuration.h" > +#include <winternl.h> > +//#include <ntstatus.h> > + > +typedef struct QXL_MONITOR_ESCAPE { > + QXL_MONITOR_ESCAPE(DEVMODE* dev_mode) > + { > + ZeroMemory(&_head, sizeof(_head)); > + _head.x = dev_mode->dmPosition.x; > + _head.y = dev_mode->dmPosition.y; > + _head.width = dev_mode->dmPelsWidth; > + _head.height = dev_mode->dmPelsHeight; > + > + } > + QXLHead _head; > +}QXL_MONITOR_ESCAPE; > + > +typedef struct QxlCustomEscapeObj : public QXLEscapeSetCustomDisplay { > + QxlCustomEscapeObj(uint32_t bitsPerPel, uint32_t width, uint32_t height) > + { > + xres = width; > + yres = height; > + bpp = bitsPerPel; > + } > + QxlCustomEscapeObj() {}; > +}QxlCustomEscapeObj; > + > +#if (_WIN32_WINNT == _WIN32_WINNT_WIN10) > +typedef struct WDDM_CUSTOM_DISPLAY_ESCAPE { > + WDDM_CUSTOM_DISPLAY_ESCAPE(DEVMODE* dev_mode) > + { > + _ioctl = QXL_ESCAPE_SET_CUSTOM_DISPLAY; > + _custom.bpp = dev_mode->dmBitsPerPel; > + _custom.xres = dev_mode->dmPelsWidth; > + _custom.yres = dev_mode->dmPelsHeight; > + } > + int _ioctl; > + QXLEscapeSetCustomDisplay _custom; > +} WDDM_CUSTOM_DISPLAY_ESCAPE; > +typedef struct WDDM_MONITOR_CONFIG_ESCAPE { > + WDDM_MONITOR_CONFIG_ESCAPE(DisplayMode* mode) > + { > + _ioctl = QXL_ESCAPE_MONITOR_CONFIG; > + _head.id = _head.surface_id = 0; > + _head.x = mode->get_pos_x(); > + _head.y = mode->get_pos_y(); > + _head.width = mode->get_width(); > + _head.height = mode->get_height(); > + } > + int _ioctl; > + QXLHead _head; > +} WDDM_MONITOR_CONFIG_ESCAPE; > +#endif > +DisplayConfig* DisplayConfig::create_config() > +{ > + DisplayConfig* new_interface; > +#if (_WIN32_WINNT == _WIN32_WINNT_WIN10) > + //Try to open a WDDM adapter. > + new_interface = new WDDMInterface(); > + if(new_interface->type() == WDDM) { > + return new_interface; > + } > + //If that failed so clean up and assume we have an XPDM driver > + delete new_interface; > +#endif > + > + new_interface = new XPDMInterface(); > + return new_interface; > +} > + > +DisplayConfig::DisplayConfig() > + : _driver_type(INVALID_DRIVER) > + , _send_monitors_config(false) > +{} > + > +bool XPDMInterface::is_attached(DISPLAY_DEVICE* dev_info) > +{ > + return !!(dev_info->StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP); > +} > + > +bool XPDMInterface::set_monitor_state(LPCTSTR device_name, DEVMODE* > dev_mode, MONITOR_STATE state) > +{ > + dev_mode->dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION; > + if(state == MONITOR_ATTACHED) { > + return true; > + } > + > + LONG status = ChangeDisplaySettingsEx(device_name, dev_mode, NULL, > CDS_UPDATEREGISTRY, NULL); > + return (status == DISP_CHANGE_SUCCESSFUL); > +} > + > +LONG XPDMInterface::update_display_settings() > +{ > + return ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); > +} > + > +bool XPDMInterface::update_dev_mode_position(LPCTSTR device_name, > + DEVMODE* dev_mode, LONG x, LONG > y) > +{ > + //Convert the position so that the primary is always at (0,0) > + dev_mode->dmPosition.x = x; > + dev_mode->dmPosition.y = y; > + dev_mode->dmFields |= DM_POSITION; > + vd_printf("%s: setting %S at (%lu, %lu)", __FUNCTION__, device_name, > dev_mode->dmPosition.x, > + dev_mode->dmPosition.y); > + > + LONG status = ChangeDisplaySettingsEx(device_name, dev_mode, NULL, > + CDS_UPDATEREGISTRY | CDS_NORESET, > NULL); > + return (status == DISP_CHANGE_SUCCESSFUL); > +} > + > +bool XPDMInterface::custom_display_escape(LPCTSTR device_name, DEVMODE* > dev_mode) > +{ > + LONG ret; > + NTSTATUS Status (ERROR_SUCCESS); > + HDC hdc = CreateDC(device_name, NULL, NULL, NULL); > + > + if (!hdc) { > + ret = ChangeDisplaySettingsEx(device_name, dev_mode, NULL, > CDS_UPDATEREGISTRY, NULL); > + if (ret == DISP_CHANGE_BADMODE) { > + // custom resolution might not be set yet, use known resolution > + // FIXME: this causes client temporary resize... a > + // solution would involve passing custom resolution before > + // driver initialization, perhaps through registry > + dev_mode->dmPelsWidth = 640; > + dev_mode->dmPelsHeight = 480; > + ret = ChangeDisplaySettingsEx(device_name, dev_mode, NULL, > CDS_UPDATEREGISTRY, NULL); > + } > + > + vd_printf("attach %ld", ret); > + if (!(hdc = CreateDC(device_name, NULL, NULL, NULL))) { > + vd_printf("%s: failed to create DC", __FUNCTION__); > + return false; > + } > + } > + > + QxlCustomEscapeObj custom_escape(dev_mode->dmBitsPerPel, > + dev_mode->dmPelsWidth, > dev_mode->dmPelsHeight); > + > + int err = ExtEscape(hdc, QXL_ESCAPE_SET_CUSTOM_DISPLAY, > + sizeof(QXLEscapeSetCustomDisplay), (LPCSTR) &custom_escape, 0, > NULL); > + if (err <= 0) { > + vd_printf("%s: Can't set custom display, perhaps running with an > older driver?", > + __FUNCTION__); > + } > + > + if(!find_best_mode(device_name, dev_mode)) { > + Status = E_FAIL; > + } > + > + DeleteDC(hdc); > + return NT_SUCCESS(Status); > +} > + > +bool XPDMInterface::update_monitor_config(LPCTSTR device_name, DisplayMode* > mode, > + DEVMODE* dev_mode) > +{ > + if(!mode || !mode->get_attached()) { > + return false; > + } > + > + QXL_MONITOR_ESCAPE monitor_config(dev_mode); > + HDC hdc(CreateDC(device_name, NULL, NULL, NULL)); > + int err(0); > + > + if (!hdc || !_send_monitors_config) { > + return false; > + } > + > + err = ExtEscape(hdc, QXL_ESCAPE_MONITOR_CONFIG, sizeof(QXLHead), > + (LPCSTR) &monitor_config, 0, NULL); > + if (err < 0) { > + vd_printf("%s: %S can't update monitor config, may have old, old > driver", > + __FUNCTION__, device_name); > + } > + DeleteDC(hdc); > + return (err >= 0); > +} > + > +bool XPDMInterface::find_best_mode(LPCTSTR Device, DEVMODE* dev_mode) > +{ > + DWORD closest_diff = -1; > + DWORD best = -1; > + > + // force refresh mode table > + DEVMODE test_dev_mode; > + ZeroMemory(&test_dev_mode, sizeof(test_dev_mode)); > + test_dev_mode.dmSize = sizeof(DEVMODE); > + EnumDisplaySettings(Device, 0xffffff, &test_dev_mode); > + > + //Find the closest size which will fit within the monitor > + for(DWORD i = 0; EnumDisplaySettings(Device, i, &test_dev_mode); i++) { > + if (dev_mode->dmPelsWidth > test_dev_mode.dmPelsWidth || > + dev_mode->dmPelsHeight > test_dev_mode.dmPelsHeight || > + dev_mode->dmBitsPerPel != test_dev_mode.dmBitsPerPel) { > + continue; > + } > + DWORD wdiff = dev_mode->dmPelsWidth - test_dev_mode.dmPelsWidth; > + DWORD hdiff = dev_mode->dmPelsHeight - test_dev_mode.dmPelsHeight; > + DWORD diff = wdiff * wdiff + hdiff * hdiff; > + if (diff < closest_diff) { > + closest_diff = diff; > + best = i; > + } > + } > + vd_printf("%s: closest_diff at %lu best %lu", __FUNCTION__, > closest_diff, best); > + if (best == (DWORD) -1 || !EnumDisplaySettings(Device, best, dev_mode)) > { > + return false; > + } > + > + //Change to the best fit > + LONG status = ChangeDisplaySettingsEx(Device, dev_mode, NULL, > + CDS_UPDATEREGISTRY | CDS_NORESET, > NULL); > + return NT_SUCCESS(status); > +} > +#if (_WIN32_WINNT == _WIN32_WINNT_WIN10) > +WDDMInterface::WDDMInterface() > + : _pfnOpen_adapter_hdc(NULL) > + , _pfnClose_adapter(NULL) > + , _pfnEscape(NULL) > + , _pfnOpen_adapter_device_name(NULL) > + , _pfnOpen_adapter_gdi_name(NULL) > +{ > + _driver_type = INVALID_DRIVER; > + > + //Did the CCD load? > + if(_ccd.error() == ERROR_NOT_SUPPORTED){ > + return; > + } > + > + //Can we find the D3D calls we need? > + if (!init_d3d_api()) { > + return; > + } > + > + //Initialize CCD path stuff > + if (!_ccd.query_display_config()){ > + return;; > + } > + if(!_ccd.set_display_config()) { > + return; > + } > + _driver_type = WDDM; > +} > + > +WDDMInterface::~WDDMInterface() > +{ > + if (_driver_type != WDDM) { > + vd_printf("%s called with invalid driver type of %d", __FUNCTION__, > _driver_type); > + return; > + } > +} > + > +bool WDDMInterface::is_attached(DISPLAY_DEVICE* dev_info) > +{ > + return _ccd.is_attached(dev_info->DeviceName); > +} > + > +bool WDDMInterface::set_monitor_state(LPCTSTR device_name, DEVMODE* > dev_mode, MONITOR_STATE state) > +{ > + return _ccd.set_path_state(device_name, state); > +} > + > +bool WDDMInterface::custom_display_escape(LPCTSTR device_name, DEVMODE* > dev_mode) > +{ > + DISPLAYCONFIG_MODE_INFO* mode = _ccd.get_active_mode(device_name, > false); > + if (!mode) { > + return false; > + } > + > + //Don't bother if we are already set to the new resolution > + if (mode->sourceMode.width == dev_mode->dmPelsWidth && > + mode->sourceMode.height == dev_mode->dmPelsHeight) { > + return true; > + } > + > + vd_printf("%s: updating %S resolution\n", __FUNCTION__, device_name); > + > + WDDM_CUSTOM_DISPLAY_ESCAPE wddm_escape (dev_mode); > + if(escape(device_name, &wddm_escape, sizeof(wddm_escape))) { > + return _ccd.update_mode_size(device_name, dev_mode); > + } > + > + vd_printf("%s: (%dx%d)", __FUNCTION__, mode->sourceMode.width, > mode->sourceMode.height); > + return false; > +} > + > +bool WDDMInterface::update_monitor_config(LPCTSTR device_name, DisplayMode* > display_mode, > + DEVMODE* dev_mode) > +{ > + if(!display_mode || !display_mode->get_attached()) { > + return false; > + } > + DISPLAYCONFIG_MODE_INFO* mode = _ccd.get_active_mode(device_name, > false); > + if (!mode || !_send_monitors_config) > + return false; > + > + WDDM_MONITOR_CONFIG_ESCAPE wddm_escape(display_mode); > + if(escape(device_name, &wddm_escape, sizeof(wddm_escape))) { > + //Update the path position > + return _ccd.update_mode_position(device_name, dev_mode); > + } > + > + vd_printf("%s: %S failed", __FUNCTION__, device_name); > + return false; > + > +} > + > +LONG WDDMInterface::update_display_settings() > +{ > + //If we removed the primary monitor since the last call, we need to > + //reorder the other monitors, making the leftmost one the primary > + _ccd.verify_primary_position(); > + > + if (!_ccd.set_display_config()) { > + if(_ccd._error != ERROR_INVALID_PARAMETER) { > + vd_printf("%s: set_display_config failed", __FUNCTION__); > + } > + else { > + vd_printf("%s: Invalid parameter!", __FUNCTION__); > + _ccd.debug_print_config("After error"); > + } > + } > + return _ccd.error(); > +} > + > +void WDDMInterface::update_config_path() > +{ > + _ccd.query_display_config(); > +} > + > +bool WDDMInterface::update_dev_mode_position(LPCTSTR device_name, DEVMODE* > dev_mode, > + LONG x, LONG y) > +{ > + //Convert the position so that the primary is always at (0,0) > + dev_mode->dmPosition.x = x; > + dev_mode->dmPosition.y = y; > + _ccd.update_mode_position(device_name, dev_mode); > + return true; > +} > + > +bool WDDMInterface::init_d3d_api() > +{ > + HMODULE hModule = LoadLibrary(L"gdi32.dll"); > + > + //Look for the gdi32 functions we need to perform driver escapes > + if(!hModule) { > + vd_printf("%s something wildly wrong as we can't open gdi32.dll", > __FUNCTION__); > + _driver_type = INVALID_DRIVER; > + return false; > + } > + > + do { > + _pfnClose_adapter = (PFND3DKMT_CLOSEADAPTER) > + GetProcAddress(hModule, "D3DKMTCloseAdapter"); > + if (!_pfnClose_adapter) { > + break; > + } > + > + _pfnEscape = (PFND3DKMT_ESCAPE) GetProcAddress(hModule, > "D3DKMTEscape"); > + if (!_pfnEscape) { > + break; > + } > + > + _pfnOpen_adapter_hdc = (PFND3DKMT_OPENADAPTERFROMHDC) > + GetProcAddress(hModule, "D3DKMTOpenAdapterFromHdc"); > + if (!_pfnOpen_adapter_hdc) { > + break; > + } > + > + _pfnOpen_adapter_device_name = (PFND3DKMT_OPENADAPTERFROMDEVICENAME) > + GetProcAddress(hModule, "D3DKMTOpenAdapterFromDeviceName"); > + if (!_pfnOpen_adapter_device_name) { > + break; > + } > + > + _pfnOpen_adapter_gdi_name = > (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME) > + GetProcAddress(hModule, "D3DKMTOpenAdapterFromGdiDisplayName"); > + if (!_pfnOpen_adapter_gdi_name) { > + break; > + } > + > + } > + while(0); > + > + FreeLibrary(hModule); > + > + //Did we get them ? > + if (!_pfnClose_adapter || !_pfnOpen_adapter_hdc || !_pfnEscape) { > + return false; > + } > + _driver_type = WDDM; > + return true; > +} > + > +D3DKMT_HANDLE WDDMInterface::adapter_handle(LPCTSTR device_name) > +{ > + D3DKMT_HANDLE hAdapter(0); > + > + //For some reason, unknown to me, this call will occasionally fail. > + if ((hAdapter = handle_from_DC(device_name))) { > + return hAdapter; > + } > + //So try other available methods. > + if (_pfnOpen_adapter_device_name && (hAdapter = > handle_from_device_name(device_name))) { > + return hAdapter; > + } > + //One last chance to open this guy > + if(_pfnOpen_adapter_gdi_name) { > + hAdapter = handle_from_GDI_name(device_name); > + } > + > + if(!hAdapter) { > + vd_printf("%s: failed to open adapter %S", __FUNCTION__, > device_name); > + } > + > + return hAdapter; > +} > + > +D3DKMT_HANDLE WDDMInterface::handle_from_DC(LPCTSTR adapter_name) > +{ > + NTSTATUS status; > + D3DKMT_OPENADAPTERFROMHDC open_data; > + HDC hDc(CreateDC(adapter_name, NULL, NULL, NULL)); > + > + if (!hDc) { > + vd_printf("%s: %S CreateDC failed with %lu", __FUNCTION__, > adapter_name, GetLastError()); > + return 0; > + } > + > + ZeroMemory(&open_data, sizeof(D3DKMT_OPENADAPTERFROMHDC)); > + open_data.hDc = hDc; > + > + if (!NT_SUCCESS(status = _pfnOpen_adapter_hdc(&open_data))) { > + vd_printf("%s: %S open adapter from hdc failed with %lu", > __FUNCTION__, adapter_name, > + status); > + open_data.hAdapter = 0; > + } > + > + DeleteDC(hDc); > + return open_data.hAdapter; > +} > + > +D3DKMT_HANDLE WDDMInterface::handle_from_device_name(LPCTSTR adapter_name) > +{ > + D3DKMT_OPENADAPTERFROMDEVICENAME display_name_data; > + NTSTATUS status; > + > + ZeroMemory(&display_name_data, sizeof(display_name_data)); > + display_name_data.pDeviceName = adapter_name; > + > + if (NT_SUCCESS(status = > _pfnOpen_adapter_device_name(&display_name_data))) { > + return display_name_data.hAdapter; > + } > + > + vd_printf("%s %S failed with 0x%lx", __FUNCTION__, adapter_name, > status); > + return 0; > +} > + > +D3DKMT_HANDLE WDDMInterface::handle_from_GDI_name(LPCTSTR adapter_name) > +{ > + D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME gdi_display_name; > + NTSTATUS status; > + > + ZeroMemory(&gdi_display_name, sizeof(gdi_display_name)); > + memcpy((void *) gdi_display_name.DeviceName, adapter_name, > sizeof(TCHAR)* CCHDEVICENAME); > + > + if (NT_SUCCESS(status = _pfnOpen_adapter_gdi_name(&gdi_display_name))) { > + return gdi_display_name.hAdapter; > + } > + > + vd_printf("%s: %S aurrrgghh nothing works..error is 0x%lx", > __FUNCTION__, adapter_name, > + status); > + return 0; > +} > + > +void WDDMInterface::close_adapter(D3DKMT_HANDLE handle) > +{ > + D3DKMT_CLOSEADAPTER closeData; > + if (handle ){ > + closeData.hAdapter = handle; > + _pfnClose_adapter(&closeData); > + } > +} > + > +bool WDDMInterface::escape(LPCTSTR device_name, void* data, UINT size_data) > +{ > + D3DKMT_ESCAPE escapeData; > + NTSTATUS status; > + D3DKMT_HANDLE hAdapter(0); > + > + if (!(hAdapter = adapter_handle(device_name))) > + return false; > + > + escapeData.hAdapter = hAdapter; > + escapeData.hDevice = 0; > + escapeData.hContext = 0; > + escapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE; > + escapeData.Flags.Value = 0; > + escapeData.pPrivateDriverData = data; > + escapeData.PrivateDriverDataSize = size_data; > + > + status = _pfnEscape(&escapeData); > + > + if (!NT_SUCCESS(status)) { > + vd_printf("%s: this should never happen. Status is 0x%lx", > __FUNCTION__, status); > + _driver_type = INVALID_DRIVER; > + } > + > + //Close the handle to this device > + close_adapter(hAdapter); > + return NT_SUCCESS(status); > +} > + > +CCD::CCD() > + :_NumPathElements(0) > + ,_NumModeElements(0) > + ,_pPathInfo(NULL) > + ,_pModeInfo(NULL) > + ,_pfnGetDeviceInfo(NULL) > + ,_pfnGetDisplayConfigBufferSizes(NULL) > + ,_pfnQueryDisplayConfig(NULL) > + ,_pfnSetDisplayConfig(NULL) > + ,_error(0) > + ,_primary_detached(false) > + ,_path_state(PATH_UPDATED) > +{ > + if(load_api()) { > + get_config_buffers(); > + } > +} > + > +CCD::~CCD() > +{ > + free_config_buffers(); > +} > + > +bool CCD::query_display_config() > +{ > + LONG query_error(ERROR_SUCCESS); > + > + //Until we get it or error != ERROR_INSUFFICIENT_BUFFER > + do { > + query_error = _pfnQueryDisplayConfig(QDC_ALL_PATHS, > &_NumPathElements, _pPathInfo, > + &_NumModeElements, _pModeInfo, NULL); > + > + // if ERROR_INSUFFICIENT_BUFFER need to retry QueryDisplayConfig > + // to get a new set of config buffers > + //(see > https://msdn.microsoft.com/en-us/library/windows/hardware/ff569215(v=vs.85).aspx > ) > + if (query_error) { > + if (query_error == ERROR_INSUFFICIENT_BUFFER) { > + free_config_buffers(); > + if (!get_config_buffers()) > + return false; > + } > + else { > + _error = query_error; > + vd_printf("%s failed QueryDisplayConfig with 0x%lx", > __FUNCTION__, _error); > + return false; > + } > + } > + } while(query_error); > + _path_state = PATH_CURRENT; > + return true; > +} > + > +DISPLAYCONFIG_MODE_INFO* CCD::get_active_mode(LPCTSTR device_name, bool > return_on_error) > +{ > + DISPLAYCONFIG_PATH_INFO* active_path; > + > + active_path = get_device_path(device_name, true); > + > + if (!active_path ) { > + vd_printf("%s:%S failed", __FUNCTION__, device_name); > + return NULL; > + } > + return &_pModeInfo[active_path->sourceInfo.modeInfoIdx]; > +} > + > +bool CCD::set_display_config() { > + > + debug_print_config("Before SetDisplayConfig"); > + > + if (_path_state == PATH_CURRENT) { > + vd_printf("%s: path states says nothing changed", __FUNCTION__); > + return true; > + } > + > + if(!(_error = _pfnSetDisplayConfig(_NumPathElements, _pPathInfo, > + _NumModeElements, _pModeInfo, > + SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | > SDC_FORCE_MODE_ENUMERATION))) > + { > + return true; > + } > + > + vd_printf("%s failed SetDisplayConfig with 0x%lx", __FUNCTION__, > _error); > + debug_print_config("After failed SetDisplayConfig"); > + return false; > +} > + > +DISPLAYCONFIG_PATH_INFO* CCD::get_device_path(LPCTSTR device_name, bool > bActive) > +{ > + //Search for device's active path > + for(UINT32 i = 0; i < _NumPathElements; i++) { > + DISPLAYCONFIG_PATH_INFO* path_info = &_pPathInfo[i]; > + > + //if bActive, return only paths that are currently active > + if(bActive && !is_active_path(path_info)) > + continue; > + if (!is_device_path(device_name, path_info)) > + continue; > + return path_info; > + } > + _error = ERROR_GEN_FAILURE; > + return NULL; > +} > + > +void CCD::debug_print_config(const char* prefix) > +{ > + TCHAR dev_name[CCHDEVICENAME]; > + for (UINT32 i = 0; i < _NumPathElements; i++) { > + DISPLAYCONFIG_PATH_INFO* path_info = &_pPathInfo[i]; > + if (!(path_info->flags & DISPLAYCONFIG_PATH_ACTIVE)) > + continue; > + get_device_name_config(path_info, dev_name); > + > + if (path_info->sourceInfo.modeInfoIdx == > DISPLAYCONFIG_PATH_MODE_IDX_INVALID) { > + vd_printf("%s: %S [%s] This path is active but has invalid mode > set.", __FUNCTION__, > + dev_name, prefix); > + continue; > + } > + DISPLAYCONFIG_MODE_INFO* mode = > &_pModeInfo[path_info->sourceInfo.modeInfoIdx]; > + vd_printf("%s: %S [%s] (%u,%u) (%ux%u).", __FUNCTION__, dev_name, > prefix, > + mode->sourceMode.position.x, mode->sourceMode.position.y, > + mode->sourceMode.width, mode->sourceMode.height); > + } > +} > + > +bool CCD::load_api() > +{ > + HMODULE hModule = LoadLibrary(L"user32.dll"); > + if(!hModule) { > + return false; > + } > + > + bool bFound_all(false); > + do { > + if(!(_pfnGetDeviceInfo = (PDISPLAYCONFIG_GETDEVICEINFO) > + GetProcAddress(hModule, "DisplayConfigGetDeviceInfo"))) { > + break; > + } > + > + if(!(_pfnGetDisplayConfigBufferSizes = > (PGETDISPLAYCONFIG_BUFFERSIZES) > + GetProcAddress(hModule, "GetDisplayConfigBufferSizes"))) { > + break; > + } > + > + if(!(_pfnQueryDisplayConfig = (PQUERYDISPLAYCONFIG) > + GetProcAddress(hModule, "QueryDisplayConfig"))) { > + break; > + } > + > + if(!(_pfnSetDisplayConfig = (PSETDISPLAYCONFIG) > + GetProcAddress(hModule, "SetDisplayConfig"))) { > + break; > + } > + bFound_all = true; > + } > + while(0); > + > + FreeLibrary(hModule); > + return bFound_all; > +} > + > +bool CCD::get_config_buffers() > +{ > + //Get Config Buffer Sizes > + free_config_buffers(); > + _error = _pfnGetDisplayConfigBufferSizes(QDC_ALL_PATHS, > &_NumPathElements, > + &_NumModeElements); > + if (_error) { > + vd_printf("%s: GetDisplayConfigBufferSizes failed with 0x%lx", > __FUNCTION__, _error); > + return false; > + } > + > + //Allocate arrays > + _pPathInfo = ((DISPLAYCONFIG_PATH_INFO*) > malloc(sizeof(DISPLAYCONFIG_PATH_INFO) * _NumPathElements)); > + _pModeInfo = ((DISPLAYCONFIG_MODE_INFO*) > malloc(sizeof(DISPLAYCONFIG_MODE_INFO) * _NumModeElements)); > + > + if (!_pPathInfo || !_pModeInfo) { > + vd_printf("%s OOM ", __FUNCTION__); > + return false; > + } > + > + ///clear the above arrays > + ZeroMemory(_pPathInfo, sizeof(DISPLAYCONFIG_PATH_INFO) * > _NumPathElements); > + ZeroMemory(_pModeInfo, sizeof(DISPLAYCONFIG_MODE_INFO) * > _NumModeElements); > + return true; > +} > + > +void CCD::free_config_buffers() > +{ > + if (_pModeInfo) { > + free(_pModeInfo); > + _pModeInfo = NULL; > + } > + if (_pPathInfo) { > + free(_pPathInfo); > + _pPathInfo = NULL; > + } > + _NumModeElements = _NumPathElements = 0; > +} > + > +bool CCD::get_device_name_config(DISPLAYCONFIG_PATH_INFO* path, LPCTSTR > dev_name) > +{ > + DISPLAYCONFIG_SOURCE_DEVICE_NAME source_name; > + source_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; > + source_name.header.size = sizeof(DISPLAYCONFIG_SOURCE_DEVICE_NAME); > + source_name.header.adapterId = path->sourceInfo.adapterId; > + source_name.header.id = path->sourceInfo.id; > + > + _error = _pfnGetDeviceInfo(&source_name.header); > + if (_error) { > + vd_printf("%s DisplayConfigGetDeviceInfo failed with %lu", > __FUNCTION__, _error); > + return false; > + } > + memcpy((void *)dev_name, source_name.viewGdiDeviceName, CCHDEVICENAME* > sizeof(TCHAR)); > + return true; > +} > + > +bool CCD::is_device_path(LPCTSTR device_name, DISPLAYCONFIG_PATH_INFO* path) > +{ > + //Does this path belong to device_name? > + TCHAR dev_name[CCHDEVICENAME]; > + if (!get_device_name_config(path, dev_name)) { > + return false; > + } > + if (_tcscmp(dev_name, device_name)) { > + return false; > + } > + return true; > +} > + > +// If we have detached the primary monitor, then we need to reset the > positions of the remaining > +// monitors to insure that at least one is positioned at (0,0) > +bool CCD::verify_primary_position() > +{ > + LONG leftmost_x(0); > + if(!_primary_detached) { > + return true; > + } > + _primary_detached = false; > + > + for (UINT32 i = 0; i < _NumPathElements; i++) { > + DISPLAYCONFIG_PATH_INFO* path_info = &_pPathInfo[i]; > + if (!(path_info->flags & DISPLAYCONFIG_PATH_ACTIVE)) > + continue; > + > + DISPLAYCONFIG_MODE_INFO* mode = > &_pModeInfo[path_info->sourceInfo.modeInfoIdx]; > + if (leftmost_x > mode->sourceMode.position.x) { > + leftmost_x = mode->sourceMode.position.x; > + } > + } > + > + if (leftmost_x == 0) { > + return false; > + } > + > + for (UINT32 i = 0; i < _NumPathElements; i++) { > + DISPLAYCONFIG_PATH_INFO* path_info = &_pPathInfo[i]; > + if ((!(path_info->flags & DISPLAYCONFIG_PATH_ACTIVE))) > + continue; > + DISPLAYCONFIG_MODE_INFO* mode = > &_pModeInfo[path_info->sourceInfo.modeInfoIdx]; > + vd_printf("%s: setting mode x to %lu", __FUNCTION__, > mode->sourceMode.position.x); > + mode->sourceMode.position.x -= leftmost_x; > + } > + _path_state = PATH_UPDATED; > + return true; > +} > + > +bool CCD::update_mode_position(LPCTSTR device_name, DEVMODE* dev_mode) > +{ > + DISPLAYCONFIG_MODE_INFO* mode = get_active_mode(device_name, false); > + if (!mode) > + return false; > + > + mode->sourceMode.position.x = dev_mode->dmPosition.x; > + mode->sourceMode.position.y = dev_mode->dmPosition.y; > + vd_printf("%s: %S updated path mode to (%lu, %lu) - (%u x%u)", > __FUNCTION__, > + device_name, > + mode->sourceMode.position.x, mode->sourceMode.position.y, > + mode->sourceMode.width, mode->sourceMode.height); > + _path_state = PATH_UPDATED; > + return true; > + > +} > + > +bool CCD::update_mode_size(LPCTSTR device_name, DEVMODE* dev_mode) > +{ > + DISPLAYCONFIG_MODE_INFO* mode = get_active_mode(device_name, false); > + if (!mode) { > + return false; > + } > + > + mode->sourceMode.width = dev_mode->dmPelsWidth; > + mode->sourceMode.height = dev_mode->dmPelsHeight; > + vd_printf("%s: %S updated path mode to (%lu, %lu - (%u x %u)", > __FUNCTION__, > + device_name, > + mode->sourceMode.position.x, mode->sourceMode.position.y, > + mode->sourceMode.width, mode->sourceMode.height); > + _path_state = PATH_UPDATED; > + return true; > +} > + > +void CCD::update_detached_primary_state(LPCTSTR device_name, > DISPLAYCONFIG_PATH_INFO * path_info) > +{ > + DISPLAYCONFIG_MODE_INFO* mode(get_active_mode(device_name, false)); > + > + //will need to reset monitor positions if primary detached > + path_info->flags = path_info->flags & ~DISPLAYCONFIG_PATH_ACTIVE; > + if (!mode|| mode->sourceMode.position.x != 0 || > mode->sourceMode.position.y != 0) { > + return ; > + } > + _primary_detached = true; > +} > + > +bool CCD::set_path_state(LPCTSTR device_name, MONITOR_STATE new_state) > +{ > + DISPLAYCONFIG_PATH_INFO* path(get_device_path(device_name, false)); > + MONITOR_STATE current_path_state(MONITOR_DETACHED); > + > + if(path && (path->flags & DISPLAYCONFIG_PATH_ACTIVE)) { > + current_path_state = MONITOR_ATTACHED; > + } > + > + //If state didn't change, nothing to do > + if(current_path_state == new_state ) { > + return true; > + } > + > + if(!path) { > + return false; > + } > + > + _path_state = PATH_UPDATED; > + if (new_state == MONITOR_DETACHED) { > + update_detached_primary_state(device_name, path); > + } > + else { > + path->flags = path->flags | DISPLAYCONFIG_PATH_ACTIVE; > + } > + return true; > +} > + > +bool CCD::is_attached(LPCTSTR device_name) > +{ > + DISPLAYCONFIG_PATH_INFO* path(get_device_path(device_name, false)); > + if(!path) { > + return false; > + } > + return (path->flags & DISPLAYCONFIG_PATH_ACTIVE); > +} > + > +bool CCD::is_active_path(DISPLAYCONFIG_PATH_INFO * path) > +{ > + if(!path || !(path->flags & DISPLAYCONFIG_PATH_ACTIVE) || > + (path->sourceInfo.modeInfoIdx == > DISPLAYCONFIG_PATH_MODE_IDX_INVALID)) { > + return false; > + } > + return true; > +} > +#endif > \ No newline at end of file > 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; > diff --git a/vdagent/vdagent.vcxproj b/vdagent/vdagent.vcxproj > new file mode 100644 > index 0000000..4f6f54a > --- /dev/null > +++ b/vdagent/vdagent.vcxproj > @@ -0,0 +1,380 @@ > +<?xml version="1.0" encoding="utf-8"?> > +<Project DefaultTargets="Build" ToolsVersion="14.0" > xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> > + <ItemGroup Label="ProjectConfigurations"> > + <ProjectConfiguration Include="Debug|Win32"> > + <Configuration>Debug</Configuration> > + <Platform>Win32</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Debug|x64"> > + <Configuration>Debug</Configuration> > + <Platform>x64</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Release|Win32"> > + <Configuration>Release</Configuration> > + <Platform>Win32</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Release|x64"> > + <Configuration>Release</Configuration> > + <Platform>x64</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Win10 Debug|Win32"> > + <Configuration>Win10 Debug</Configuration> > + <Platform>Win32</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Win10 Debug|x64"> > + <Configuration>Win10 Debug</Configuration> > + <Platform>x64</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Win10 Release|Win32"> > + <Configuration>Win10 Release</Configuration> > + <Platform>Win32</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Win10 Release|x64"> > + <Configuration>Win10 Release</Configuration> > + <Platform>x64</Platform> > + </ProjectConfiguration> > + </ItemGroup> > + <PropertyGroup Label="Globals"> > + <ProjectGuid>{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}</ProjectGuid> > + <RootNamespace>redagent</RootNamespace> > + <Keyword>Win32Proj</Keyword> > + > <WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion> > + </PropertyGroup> > + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + <WholeProgramOptimization>true</WholeProgramOptimization> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|Win32'" Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + <WholeProgramOptimization>true</WholeProgramOptimization> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|x64'" Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <PropertyGroup Label="Configuration" > Condition="'$(Configuration)|$(Platform)'=='Win10 Release|Win32'"> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <PropertyGroup Label="Configuration" > Condition="'$(Configuration)|$(Platform)'=='Win10 Release|x64'"> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> > + <ImportGroup Label="ExtensionSettings"> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|Win32'" Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Win10 Debug|x64'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Label="PropertySheets" > Condition="'$(Configuration)|$(Platform)'=='Win10 Release|x64'"> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Label="PropertySheets" > Condition="'$(Configuration)|$(Platform)'=='Win10 Release|Win32'"> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <PropertyGroup Label="UserMacros" /> > + <PropertyGroup> > + <_ProjectFileVersion>14.0.23107.0</_ProjectFileVersion> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> > + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> > + <IntDir>$(Configuration)\</IntDir> > + <LinkIncremental>true</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|Win32'"> > + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> > + <IntDir>$(Configuration)\</IntDir> > + <LinkIncremental>true</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> > + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> > + <IntDir>$(Platform)\$(Configuration)\</IntDir> > + <LinkIncremental>true</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|x64'"> > + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> > + <IntDir>$(Platform)\$(Configuration)\</IntDir> > + <LinkIncremental>true</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup > Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> > + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> > + <IntDir>$(Configuration)\</IntDir> > + <LinkIncremental>false</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> > + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> > + <IntDir>$(Platform)\$(Configuration)\</IntDir> > + <LinkIncremental>false</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Release|x64'"> > + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> > + </PropertyGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> > + <ClCompile> > + <Optimization>Disabled</Optimization> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <MinimalRebuild>true</MinimalRebuild> > + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> > + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_DEBUG_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_DEBUG_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Windows</SubSystem> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX86</TargetMachine> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|Win32'"> > + <ClCompile> > + <Optimization>Disabled</Optimization> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;$(WindowsSdkDir)\Include\$(TargetPlatformVersion);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=_WIN32_WINNT_WIN10;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <MinimalRebuild>true</MinimalRebuild> > + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> > + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> > + <PrecompiledHeader> > + </PrecompiledHeader> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_DEBUG_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_DEBUG_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Windows</SubSystem> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention> > + </DataExecutionPrevention> > + <TargetMachine>MachineX86</TargetMachine> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> > + <Midl> > + <TargetEnvironment>X64</TargetEnvironment> > + </Midl> > + <ClCompile> > + <Optimization>Disabled</Optimization> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <MinimalRebuild>true</MinimalRebuild> > + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> > + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_DEBUG_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_DEBUG_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Windows</SubSystem> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX64</TargetMachine> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Debug|x64'"> > + <Midl> > + <TargetEnvironment>X64</TargetEnvironment> > + </Midl> > + <ClCompile> > + <Optimization>Disabled</Optimization> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;$(WindowsSdkDir)\Include\$(TargetPlatformVersion);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <MinimalRebuild>true</MinimalRebuild> > + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> > + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> > + <PrecompiledHeader> > + </PrecompiledHeader> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_DEBUG_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_DEBUG_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Windows</SubSystem> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention> > + </DataExecutionPrevention> > + <TargetMachine>MachineX64</TargetMachine> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> > + <ClCompile> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_LIBS_DIR);$(SPICE_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Windows</SubSystem> > + <OptimizeReferences>true</OptimizeReferences> > + <EnableCOMDATFolding>true</EnableCOMDATFolding> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX86</TargetMachine> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> > + <Midl> > + <TargetEnvironment>X64</TargetEnvironment> > + </Midl> > + <ClCompile> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Windows</SubSystem> > + <OptimizeReferences>true</OptimizeReferences> > + <EnableCOMDATFolding>true</EnableCOMDATFolding> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX64</TargetMachine> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Release|x64'"> > + <ClCompile> > + > <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=_WIN32_WINNT_WIN10;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;$(WindowsSdkDir)\Include\$(TargetPlatformVersion);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Win10 > Release|Win32'"> > + <ClCompile> > + > <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_WIN32_WINNT=_WIN32_WINNT_WIN10;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage;$(WindowsSdkDir)\Include\$(TargetPlatformVersion);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> > + <WholeProgramOptimization>true</WholeProgramOptimization> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>Version.lib;$(SPICE_LIB_LIST);wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> > + > <AdditionalLibraryDirectories>$(SPICE_LIBS_DIR);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> > + </Link> > + <PostBuildEvent> > + <Command> > + </Command> > + </PostBuildEvent> > + </ItemDefinitionGroup> > + <ItemGroup> > + <ClCompile Include="..\common\vdcommon.cpp" /> > + <ClCompile Include="..\common\vdlog.cpp" /> > + <ClCompile Include="as_user.cpp" /> > + <ClCompile Include="desktop_layout.cpp" /> > + <ClCompile Include="display_configuration.cpp" /> > + <ClCompile Include="display_setting.cpp" /> > + <ClCompile Include="file_xfer.cpp" /> > + <ClCompile Include="vdagent.cpp" /> > + </ItemGroup> > + <ItemGroup> > + <ClInclude Include="..\common\vdcommon.h" /> > + <ClInclude Include="..\common\vdlog.h" /> > + <ClInclude Include="as_user.h" /> > + <ClInclude Include="CCD.h" /> > + <ClInclude Include="desktop_layout.h" /> > + <ClInclude Include="display_configuration.h" /> > + <ClInclude Include="display_setting.h" /> > + <ClInclude Include="driver_interface.h" /> > + <ClInclude Include="file_xfer.h" /> > + <ClInclude Include="resource.h" /> > + </ItemGroup> > + <ItemGroup> > + <ResourceCompile Include="vdagent.rc" /> > + </ItemGroup> > + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> > + <ImportGroup Label="ExtensionTargets"> > + </ImportGroup> > +</Project> > \ No newline at end of file > diff --git a/vdservice/vdservice.vcxproj b/vdservice/vdservice.vcxproj > new file mode 100644 > index 0000000..7ea66ea > --- /dev/null > +++ b/vdservice/vdservice.vcxproj > @@ -0,0 +1,197 @@ > +<?xml version="1.0" encoding="utf-8"?> > +<Project DefaultTargets="Build" ToolsVersion="14.0" > xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> > + <ItemGroup Label="ProjectConfigurations"> > + <ProjectConfiguration Include="Debug|Win32"> > + <Configuration>Debug</Configuration> > + <Platform>Win32</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Debug|x64"> > + <Configuration>Debug</Configuration> > + <Platform>x64</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Release|Win32"> > + <Configuration>Release</Configuration> > + <Platform>Win32</Platform> > + </ProjectConfiguration> > + <ProjectConfiguration Include="Release|x64"> > + <Configuration>Release</Configuration> > + <Platform>x64</Platform> > + </ProjectConfiguration> > + </ItemGroup> > + <PropertyGroup Label="Globals"> > + <ProjectGuid>{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}</ProjectGuid> > + <RootNamespace>redservice</RootNamespace> > + <Keyword>Win32Proj</Keyword> > + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> > + </PropertyGroup> > + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + <WholeProgramOptimization>true</WholeProgramOptimization> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + <WholeProgramOptimization>true</WholeProgramOptimization> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" > Label="Configuration"> > + <ConfigurationType>Application</ConfigurationType> > + <PlatformToolset>v140</PlatformToolset> > + <CharacterSet>Unicode</CharacterSet> > + </PropertyGroup> > + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> > + <ImportGroup Label="ExtensionSettings"> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" > Label="PropertySheets"> > + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" > Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" > Label="LocalAppDataPlatform" /> > + <Import Project="..\Spice.props" /> > + </ImportGroup> > + <PropertyGroup Label="UserMacros" /> > + <PropertyGroup> > + <_ProjectFileVersion>14.0.23107.0</_ProjectFileVersion> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> > + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> > + <IntDir>$(Configuration)\</IntDir> > + <LinkIncremental>true</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> > + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> > + <IntDir>$(Platform)\$(Configuration)\</IntDir> > + <LinkIncremental>true</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup > Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> > + <OutDir>$(SolutionDir)$(Configuration)\</OutDir> > + <IntDir>$(Configuration)\</IntDir> > + <LinkIncremental>false</LinkIncremental> > + </PropertyGroup> > + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> > + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> > + <IntDir>$(Platform)\$(Configuration)\</IntDir> > + <LinkIncremental>false</LinkIncremental> > + </PropertyGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> > + <ClCompile> > + <Optimization>Disabled</Optimization> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <MinimalRebuild>true</MinimalRebuild> > + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> > + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>WtsApi32.lib;Userenv.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Console</SubSystem> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX86</TargetMachine> > + </Link> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> > + <Midl> > + <TargetEnvironment>X64</TargetEnvironment> > + </Midl> > + <ClCompile> > + <Optimization>Disabled</Optimization> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <MinimalRebuild>true</MinimalRebuild> > + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> > + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>WtsApi32.lib;Userenv.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Console</SubSystem> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX64</TargetMachine> > + </Link> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> > + <ClCompile> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>WtsApi32.lib;Userenv.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Console</SubSystem> > + <OptimizeReferences>true</OptimizeReferences> > + <EnableCOMDATFolding>true</EnableCOMDATFolding> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX86</TargetMachine> > + </Link> > + </ItemDefinitionGroup> > + <ItemDefinitionGroup > Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> > + <Midl> > + <TargetEnvironment>X64</TargetEnvironment> > + </Midl> > + <ClCompile> > + > <AdditionalIncludeDirectories>..\common;$(SPICE_PROTOCOL_DIR);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> > + > <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions)</PreprocessorDefinitions> > + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> > + <PrecompiledHeader /> > + <WarningLevel>Level3</WarningLevel> > + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> > + </ClCompile> > + <Link> > + > <AdditionalDependencies>WtsApi32.lib;Userenv.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> > + <GenerateDebugInformation>true</GenerateDebugInformation> > + <SubSystem>Console</SubSystem> > + <OptimizeReferences>true</OptimizeReferences> > + <EnableCOMDATFolding>true</EnableCOMDATFolding> > + <RandomizedBaseAddress>false</RandomizedBaseAddress> > + <DataExecutionPrevention /> > + <TargetMachine>MachineX64</TargetMachine> > + </Link> > + </ItemDefinitionGroup> > + <ItemGroup> > + <ClInclude Include="..\common\vdcommon.h" /> > + <ClInclude Include="..\common\vdlog.h" /> > + <ClInclude Include="resource.h" /> > + </ItemGroup> > + <ItemGroup> > + <ResourceCompile Include="vdservice.rc" /> > + </ItemGroup> > + <ItemGroup> > + <ClCompile Include="..\common\vdcommon.cpp" /> > + <ClCompile Include="..\common\vdlog.cpp" /> > + <ClCompile Include="vdservice.cpp" /> > + </ItemGroup> > + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> > + <ImportGroup Label="ExtensionTargets"> > + </ImportGroup> > +</Project> > \ No newline at end of file This patch is massive! Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel