mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-04-24 23:56:26 +00:00
[idd] driver: improve display mode support and resolution switch
This commit is contained in:
parent
6396ff1e9c
commit
7afb9b93eb
@ -28,7 +28,8 @@ struct LGPipeMsg
|
|||||||
unsigned size;
|
unsigned size;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SETCURSORPOS
|
SETCURSORPOS,
|
||||||
|
SETDISPLAYMODE
|
||||||
}
|
}
|
||||||
type;
|
type;
|
||||||
union
|
union
|
||||||
@ -39,5 +40,12 @@ struct LGPipeMsg
|
|||||||
uint32_t y;
|
uint32_t y;
|
||||||
}
|
}
|
||||||
curorPos;
|
curorPos;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
}
|
||||||
|
displayMode;
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -42,11 +42,58 @@ static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG =
|
|||||||
1000 //subTimeout
|
1000 //subTimeout
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DWORD DefaultDisplayModes[][3] =
|
||||||
|
{
|
||||||
|
{7680, 4800, 120}, {7680, 4320, 120}, {6016, 3384, 120}, {5760, 3600, 120},
|
||||||
|
{5760, 3240, 120}, {5120, 2800, 120}, {4096, 2560, 120}, {4096, 2304, 120},
|
||||||
|
{3840, 2400, 120}, {3840, 2160, 120}, {3200, 2400, 120}, {3200, 1800, 120},
|
||||||
|
{3008, 1692, 120}, {2880, 1800, 120}, {2880, 1620, 120}, {2560, 1600, 120},
|
||||||
|
{2560, 1440, 120}, {1920, 1440, 120}, {1920, 1200, 120}, {1920, 1080, 120},
|
||||||
|
{1600, 1200, 120}, {1600, 1024, 120}, {1600, 1050, 120}, {1600, 900 , 120},
|
||||||
|
{1440, 900 , 120}, {1400, 1050, 120}, {1366, 768 , 120}, {1360, 768 , 120},
|
||||||
|
{1280, 1024, 120}, {1280, 960 , 120}, {1280, 800 , 120}, {1280, 768 , 120},
|
||||||
|
{1280, 720 , 120}, {1280, 600 , 120}, {1152, 864 , 120}, {1024, 768 , 120},
|
||||||
|
{800 , 600 , 120}, {640 , 480 , 120}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const BYTE EDID[] =
|
||||||
|
{
|
||||||
|
0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x30,0xE8,0x34,0x12,0xC9,0x07,0xCC,0x00,
|
||||||
|
0x01,0x21,0x01,0x04,0xA5,0x3C,0x22,0x78,0xFB,0x6C,0xE5,0xA5,0x55,0x50,0xA0,0x23,
|
||||||
|
0x0B,0x50,0x54,0x00,0x02,0x00,0xD1,0xC0,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||||
|
0x01,0x01,0x01,0x01,0x01,0x01,0x58,0xE3,0x00,0xA0,0xA0,0xA0,0x29,0x50,0x30,0x20,
|
||||||
|
0x35,0x00,0x55,0x50,0x21,0x00,0x00,0x1A,0x00,0x00,0x00,0xFF,0x00,0x4C,0x6F,0x6F,
|
||||||
|
0x6B,0x69,0x6E,0x67,0x47,0x6C,0x61,0x73,0x73,0x0A,0x00,0x00,0x00,0xFC,0x00,0x4C,
|
||||||
|
0x6F,0x6F,0x6B,0x69,0x6E,0x67,0x20,0x47,0x6C,0x61,0x73,0x73,0x00,0x00,0x00,0xFD,
|
||||||
|
0x00,0x28,0x9B,0xFA,0xFA,0x40,0x01,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x4A
|
||||||
|
};
|
||||||
|
|
||||||
|
const DWORD DefaultPreferredDisplayMode = 19;
|
||||||
|
|
||||||
|
void CIndirectDeviceContext::PopulateDefaultModes(bool setDefaultMode)
|
||||||
|
{
|
||||||
|
m_displayModes.reserve(m_displayModes.size() +
|
||||||
|
ARRAYSIZE(DefaultDisplayModes));
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAYSIZE(DefaultDisplayModes); ++i)
|
||||||
|
{
|
||||||
|
DisplayMode m;
|
||||||
|
m.width = DefaultDisplayModes[i][0];
|
||||||
|
m.height = DefaultDisplayModes[i][1];
|
||||||
|
m.refresh = DefaultDisplayModes[i][2];
|
||||||
|
m.preferred = setDefaultMode && (i == DefaultPreferredDisplayMode);
|
||||||
|
m_displayModes.push_back(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CIndirectDeviceContext::InitAdapter()
|
void CIndirectDeviceContext::InitAdapter()
|
||||||
{
|
{
|
||||||
if (!m_ivshmem.Init() || !m_ivshmem.Open())
|
if (!m_ivshmem.Init() || !m_ivshmem.Open())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
m_displayModes.clear();
|
||||||
|
PopulateDefaultModes(true);
|
||||||
|
|
||||||
IDDCX_ADAPTER_CAPS caps = {};
|
IDDCX_ADAPTER_CAPS caps = {};
|
||||||
caps.Size = sizeof(caps);
|
caps.Size = sizeof(caps);
|
||||||
|
|
||||||
@ -114,30 +161,10 @@ void CIndirectDeviceContext::InitAdapter()
|
|||||||
}
|
}
|
||||||
factory->Release();
|
factory->Release();
|
||||||
|
|
||||||
// setup some default display modes
|
|
||||||
DisplayMode m;
|
|
||||||
m.refresh = 120;
|
|
||||||
|
|
||||||
m.width = 800 ; m.height = 600 ; m.preferred = false; m_displayModes.push_back(m);
|
|
||||||
m.width = 1024; m.height = 768 ; m.preferred = false; m_displayModes.push_back(m);
|
|
||||||
m.width = 1920; m.height = 1200; m.preferred = true ; m_displayModes.push_back(m);
|
|
||||||
|
|
||||||
auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(m_adapter);
|
auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(m_adapter);
|
||||||
wrapper->context = this;
|
wrapper->context = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const BYTE EDID[] =
|
|
||||||
{
|
|
||||||
0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x30,0xE8,0x34,0x12,0xC9,0x07,0xCC,0x00,
|
|
||||||
0x01,0x21,0x01,0x04,0xA5,0x3C,0x22,0x78,0xFB,0x6C,0xE5,0xA5,0x55,0x50,0xA0,0x23,
|
|
||||||
0x0B,0x50,0x54,0x00,0x02,0x00,0xD1,0xC0,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
|
||||||
0x01,0x01,0x01,0x01,0x01,0x01,0x58,0xE3,0x00,0xA0,0xA0,0xA0,0x29,0x50,0x30,0x20,
|
|
||||||
0x35,0x00,0x55,0x50,0x21,0x00,0x00,0x1A,0x00,0x00,0x00,0xFF,0x00,0x4C,0x6F,0x6F,
|
|
||||||
0x6B,0x69,0x6E,0x67,0x47,0x6C,0x61,0x73,0x73,0x0A,0x00,0x00,0x00,0xFC,0x00,0x4C,
|
|
||||||
0x6F,0x6F,0x6B,0x69,0x6E,0x67,0x20,0x47,0x6C,0x61,0x73,0x73,0x00,0x00,0x00,0xFD,
|
|
||||||
0x00,0x28,0x9B,0xFA,0xFA,0x40,0x01,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x4A
|
|
||||||
};
|
|
||||||
|
|
||||||
void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
|
void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
|
||||||
{
|
{
|
||||||
WDF_OBJECT_ATTRIBUTES attr;
|
WDF_OBJECT_ATTRIBUTES attr;
|
||||||
@ -210,7 +237,16 @@ void CIndirectDeviceContext::ReplugMonitor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIndirectDeviceContext::UnassignSwapChain()
|
void CIndirectDeviceContext::OnAssignSwapChain()
|
||||||
|
{
|
||||||
|
if (m_setCustomMode)
|
||||||
|
{
|
||||||
|
m_setCustomMode = false;
|
||||||
|
g_pipe.SetDisplayMode(m_customMode.width, m_customMode.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CIndirectDeviceContext::OnUnassignedSwapChain()
|
||||||
{
|
{
|
||||||
if (m_replugMonitor)
|
if (m_replugMonitor)
|
||||||
{
|
{
|
||||||
@ -300,6 +336,89 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes(
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIndirectDeviceContext::SetResolution(int width, int height)
|
||||||
|
{
|
||||||
|
m_displayModes.clear();
|
||||||
|
m_customMode.width = width;
|
||||||
|
m_customMode.height = height;
|
||||||
|
m_customMode.refresh = 120;
|
||||||
|
m_customMode.preferred = true;
|
||||||
|
m_displayModes.push_back(m_customMode);
|
||||||
|
PopulateDefaultModes(false);
|
||||||
|
|
||||||
|
m_setCustomMode = true;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
ReplugMonitor();
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (IDD_IS_FUNCTION_AVAILABLE(IddCxMonitorUpdateModes2))
|
||||||
|
{
|
||||||
|
IDDCX_TARGET_MODE2* modes = (IDDCX_TARGET_MODE2*)_malloca(
|
||||||
|
m_displayModes.size() * sizeof(IDDCX_TARGET_MODE2));
|
||||||
|
|
||||||
|
if (!modes)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate memory for the mode list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMemory(modes, m_displayModes.size() * sizeof(IDDCX_TARGET_MODE2));
|
||||||
|
|
||||||
|
IDARG_IN_UPDATEMODES2 um = {};
|
||||||
|
um.Reason = IDDCX_UPDATE_REASON_OTHER;
|
||||||
|
um.TargetModeCount = (UINT)m_displayModes.size();
|
||||||
|
um.pTargetModes = modes;
|
||||||
|
auto* mode = modes;
|
||||||
|
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
|
||||||
|
{
|
||||||
|
mode->Size = sizeof(IDDCX_TARGET_MODE2);
|
||||||
|
mode->RequiredBandwidth = (UINT64)(it->width * it->height * it->refresh * 32);
|
||||||
|
mode->BitsPerComponent.Rgb = IDDCX_BITS_PER_COMPONENT_8;
|
||||||
|
|
||||||
|
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS status = IddCxMonitorUpdateModes2(m_monitor, &um);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
DEBUG_ERROR("IddCxMonitorUpdateModes2 Failed (0x%08x)", status);
|
||||||
|
|
||||||
|
_freea(modes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IDDCX_TARGET_MODE* modes = (IDDCX_TARGET_MODE*)_malloca(
|
||||||
|
m_displayModes.size() * sizeof(IDDCX_TARGET_MODE));
|
||||||
|
|
||||||
|
if (!modes)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate memory for the mode list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDARG_IN_UPDATEMODES um = {};
|
||||||
|
um.Reason = IDDCX_UPDATE_REASON_OTHER;
|
||||||
|
um.TargetModeCount = (UINT)m_displayModes.size();
|
||||||
|
um.pTargetModes = modes;
|
||||||
|
|
||||||
|
auto* mode = modes;
|
||||||
|
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
|
||||||
|
{
|
||||||
|
mode->Size = sizeof(IDDCX_TARGET_MODE);
|
||||||
|
mode->RequiredBandwidth = (UINT64)(it->width * it->height * it->refresh * 32);
|
||||||
|
|
||||||
|
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS status = IddCxMonitorUpdateModes(m_monitor, &um);
|
||||||
|
if (!NT_SUCCESS(status))
|
||||||
|
DEBUG_ERROR("IddCxMonitorUpdateModes Failed (0x%08x)", status);
|
||||||
|
|
||||||
|
_freea(modes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool CIndirectDeviceContext::SetupLGMP(size_t alignSize)
|
bool CIndirectDeviceContext::SetupLGMP(size_t alignSize)
|
||||||
{
|
{
|
||||||
// this may get called multiple times as we need to delay calling it until
|
// this may get called multiple times as we need to delay calling it until
|
||||||
@ -522,14 +641,7 @@ void CIndirectDeviceContext::LGMPTimer()
|
|||||||
case KVMFR_MESSAGE_WINDOWSIZE:
|
case KVMFR_MESSAGE_WINDOWSIZE:
|
||||||
{
|
{
|
||||||
KVMFRWindowSize* ws = (KVMFRWindowSize*)msg;
|
KVMFRWindowSize* ws = (KVMFRWindowSize*)msg;
|
||||||
m_displayModes.clear();
|
SetResolution(ws->w, ws->h);
|
||||||
DisplayMode m;
|
|
||||||
m.width = ws->w;
|
|
||||||
m.height = ws->h;
|
|
||||||
m.refresh = 120;
|
|
||||||
m.preferred = true;
|
|
||||||
m_displayModes.push_back(m);
|
|
||||||
ReplugMonitor();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,8 @@ private:
|
|||||||
bool preferred;
|
bool preferred;
|
||||||
};
|
};
|
||||||
std::vector<DisplayMode> m_displayModes;
|
std::vector<DisplayMode> m_displayModes;
|
||||||
|
DisplayMode m_customMode = {};
|
||||||
|
bool m_setCustomMode = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
|
CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
|
||||||
@ -92,10 +94,13 @@ public:
|
|||||||
|
|
||||||
bool SetupLGMP(size_t alignSize);
|
bool SetupLGMP(size_t alignSize);
|
||||||
|
|
||||||
|
void PopulateDefaultModes(bool setDefaultMode);
|
||||||
void InitAdapter();
|
void InitAdapter();
|
||||||
void FinishInit(UINT connectorIndex);
|
void FinishInit(UINT connectorIndex);
|
||||||
void ReplugMonitor();
|
void ReplugMonitor();
|
||||||
void UnassignSwapChain();
|
|
||||||
|
void OnAssignSwapChain();
|
||||||
|
void OnUnassignedSwapChain();
|
||||||
|
|
||||||
NTSTATUS ParseMonitorDescription(
|
NTSTATUS ParseMonitorDescription(
|
||||||
const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs, IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs);
|
const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs, IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs);
|
||||||
@ -104,6 +109,8 @@ public:
|
|||||||
NTSTATUS MonitorQueryTargetModes(
|
NTSTATUS MonitorQueryTargetModes(
|
||||||
const IDARG_IN_QUERYTARGETMODES* inArgs, IDARG_OUT_QUERYTARGETMODES* outArgs);
|
const IDARG_IN_QUERYTARGETMODES* inArgs, IDARG_OUT_QUERYTARGETMODES* outArgs);
|
||||||
|
|
||||||
|
void SetResolution(int width, int height);
|
||||||
|
|
||||||
size_t GetAlignSize() { return m_alignSize; }
|
size_t GetAlignSize() { return m_alignSize; }
|
||||||
size_t GetMaxFrameSize() { return m_maxFrameSize; }
|
size_t GetMaxFrameSize() { return m_maxFrameSize; }
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ CIndirectMonitorContext::~CIndirectMonitorContext()
|
|||||||
void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent)
|
void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent)
|
||||||
{
|
{
|
||||||
reInit:
|
reInit:
|
||||||
m_swapChain.reset();
|
UnassignSwapChain();
|
||||||
|
|
||||||
m_dx11Device = std::make_shared<CD3D11Device>(renderAdapter);
|
m_dx11Device = std::make_shared<CD3D11Device>(renderAdapter);
|
||||||
if (FAILED(m_dx11Device->Init()))
|
if (FAILED(m_dx11Device->Init()))
|
||||||
{
|
{
|
||||||
|
@ -160,4 +160,17 @@ void CPipeServer::SetCursorPos(uint32_t x, uint32_t y)
|
|||||||
msg.curorPos.x = x;
|
msg.curorPos.x = x;
|
||||||
msg.curorPos.y = y;
|
msg.curorPos.y = y;
|
||||||
WriteMsg(msg);
|
WriteMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPipeServer::SetDisplayMode(uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
if (!m_connected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LGPipeMsg msg;
|
||||||
|
msg.size = sizeof(msg);
|
||||||
|
msg.type = LGPipeMsg::SETDISPLAYMODE;
|
||||||
|
msg.displayMode.width = width;
|
||||||
|
msg.displayMode.height = height;
|
||||||
|
WriteMsg(msg);
|
||||||
}
|
}
|
@ -54,6 +54,7 @@ class CPipeServer
|
|||||||
void DeInit();
|
void DeInit();
|
||||||
|
|
||||||
void SetCursorPos(uint32_t x, uint32_t y);
|
void SetCursorPos(uint32_t x, uint32_t y);
|
||||||
|
void SetDisplayMode(uint32_t width, uint32_t height);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CPipeServer g_pipe;
|
extern CPipeServer g_pipe;
|
@ -108,6 +108,7 @@ NTSTATUS LGIddMonitorAssignSwapChain(IDDCX_MONITOR monitor, const IDARG_IN_SETSW
|
|||||||
auto * wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
auto * wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
||||||
wrapper->context->AssignSwapChain(
|
wrapper->context->AssignSwapChain(
|
||||||
inArgs->hSwapChain, inArgs->RenderAdapterLuid, inArgs->hNextSurfaceAvailable);
|
inArgs->hSwapChain, inArgs->RenderAdapterLuid, inArgs->hNextSurfaceAvailable);
|
||||||
|
wrapper->context->GetDeviceContext()->OnAssignSwapChain();
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ NTSTATUS LGIddMonitorUnassignSwapChain(IDDCX_MONITOR monitor)
|
|||||||
{
|
{
|
||||||
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
|
||||||
wrapper->context->UnassignSwapChain();
|
wrapper->context->UnassignSwapChain();
|
||||||
wrapper->context->GetDeviceContext()->UnassignSwapChain();
|
wrapper->context->GetDeviceContext()->OnUnassignedSwapChain();
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,33 +24,6 @@
|
|||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#if 1
|
|
||||||
const DWORD DisplayModes[][3] =
|
|
||||||
{
|
|
||||||
{7680, 4800, 120}, {7680, 4320, 120}, {6016, 3384, 120}, {5760, 3600, 120},
|
|
||||||
{5760, 3240, 120}, {5120, 2800, 120}, {4096, 2560, 120}, {4096, 2304, 120},
|
|
||||||
{3840, 2400, 120}, {3840, 2160, 120}, {3200, 2400, 120}, {3200, 1800, 120},
|
|
||||||
{3008, 1692, 120}, {2880, 1800, 120}, {2880, 1620, 120}, {2560, 1600, 120},
|
|
||||||
{2560, 1440, 120}, {1920, 1440, 120}, {1920, 1200, 120}, {1920, 1080, 120},
|
|
||||||
{1600, 1200, 120}, {1600, 1024, 120}, {1600, 1050, 120}, {1600, 900 , 120},
|
|
||||||
{1440, 900 , 120}, {1400, 1050, 120}, {1366, 768 , 120}, {1360, 768 , 120},
|
|
||||||
{1280, 1024, 120}, {1280, 960 , 120}, {1280, 800 , 120}, {1280, 768 , 120},
|
|
||||||
{1280, 720 , 120}, {1280, 600 , 120}, {1152, 864 , 120}, {1024, 768 , 120},
|
|
||||||
{800 , 600 , 120}, {640 , 480 , 120}
|
|
||||||
};
|
|
||||||
|
|
||||||
const DWORD PreferredDisplayMode = 19;
|
|
||||||
#else
|
|
||||||
const DWORD DisplayModes[][3] =
|
|
||||||
{
|
|
||||||
{ 2560, 1440, 144 },
|
|
||||||
{ 1920, 1080, 60 },
|
|
||||||
{ 1024, 768, 60 },
|
|
||||||
};
|
|
||||||
|
|
||||||
const DWORD PreferredDisplayMode = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _DEVICE_CONTEXT
|
typedef struct _DEVICE_CONTEXT
|
||||||
{
|
{
|
||||||
ULONG PrivateDeviceData; // just a placeholder
|
ULONG PrivateDeviceData; // just a placeholder
|
||||||
|
@ -211,6 +211,10 @@ void CPipeClient::Thread()
|
|||||||
HandleSetCursorPos(msg);
|
HandleSetCursorPos(msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LGPipeMsg::SETDISPLAYMODE:
|
||||||
|
HandleSetDisplayMode(msg);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR("Unknown message type %d", msg.type);
|
DEBUG_ERROR("Unknown message type %d", msg.type);
|
||||||
break;
|
break;
|
||||||
@ -228,4 +232,17 @@ void CPipeClient::HandleSetCursorPos(const LGPipeMsg& msg)
|
|||||||
{
|
{
|
||||||
SetActiveDesktop();
|
SetActiveDesktop();
|
||||||
SetCursorPos(msg.curorPos.x, msg.curorPos.y);
|
SetCursorPos(msg.curorPos.x, msg.curorPos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPipeClient::HandleSetDisplayMode(const LGPipeMsg& msg)
|
||||||
|
{
|
||||||
|
DEVMODE dm = {};
|
||||||
|
dm.dmSize = sizeof(dm);
|
||||||
|
dm.dmPelsWidth = msg.displayMode.width;
|
||||||
|
dm.dmPelsHeight = msg.displayMode.height;
|
||||||
|
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||||
|
|
||||||
|
LONG result = ChangeDisplaySettingsEx(NULL, &dm, NULL, CDS_UPDATEREGISTRY, NULL);
|
||||||
|
if (result != DISP_CHANGE_SUCCESSFUL)
|
||||||
|
DEBUG_ERROR("ChangeDisplaySettingsEx Failed (0x%08x)", result);
|
||||||
}
|
}
|
@ -46,6 +46,7 @@ private:
|
|||||||
void SetActiveDesktop();
|
void SetActiveDesktop();
|
||||||
|
|
||||||
void HandleSetCursorPos(const LGPipeMsg& msg);
|
void HandleSetCursorPos(const LGPipeMsg& msg);
|
||||||
|
void HandleSetDisplayMode(const LGPipeMsg& msg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~CPipeClient() { DeInit(); }
|
~CPipeClient() { DeInit(); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user