mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-11-04 14:41:55 +00:00 
			
		
		
		
	[idd] driver: improve display mode support and resolution switch
This commit is contained in:
		@@ -28,7 +28,8 @@ struct LGPipeMsg
 | 
			
		||||
  unsigned size;
 | 
			
		||||
  enum
 | 
			
		||||
  {
 | 
			
		||||
    SETCURSORPOS
 | 
			
		||||
    SETCURSORPOS,
 | 
			
		||||
    SETDISPLAYMODE
 | 
			
		||||
  }
 | 
			
		||||
  type;
 | 
			
		||||
  union
 | 
			
		||||
@@ -39,5 +40,12 @@ struct LGPipeMsg
 | 
			
		||||
      uint32_t y;
 | 
			
		||||
    }
 | 
			
		||||
    curorPos;
 | 
			
		||||
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
      uint32_t width;
 | 
			
		||||
      uint32_t height;
 | 
			
		||||
    }
 | 
			
		||||
    displayMode;
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
@@ -42,11 +42,58 @@ static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG =
 | 
			
		||||
  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()
 | 
			
		||||
{
 | 
			
		||||
  if (!m_ivshmem.Init() || !m_ivshmem.Open())
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  m_displayModes.clear();
 | 
			
		||||
  PopulateDefaultModes(true);
 | 
			
		||||
 | 
			
		||||
  IDDCX_ADAPTER_CAPS caps = {};
 | 
			
		||||
  caps.Size = sizeof(caps);
 | 
			
		||||
 | 
			
		||||
@@ -114,30 +161,10 @@ void CIndirectDeviceContext::InitAdapter()
 | 
			
		||||
  }
 | 
			
		||||
  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);
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  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)
 | 
			
		||||
  {
 | 
			
		||||
@@ -300,6 +336,89 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes(
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  // 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:
 | 
			
		||||
      {
 | 
			
		||||
        KVMFRWindowSize* ws = (KVMFRWindowSize*)msg;
 | 
			
		||||
        m_displayModes.clear();
 | 
			
		||||
        DisplayMode m;
 | 
			
		||||
        m.width     = ws->w;
 | 
			
		||||
        m.height    = ws->h;
 | 
			
		||||
        m.refresh   = 120;
 | 
			
		||||
        m.preferred = true;
 | 
			
		||||
        m_displayModes.push_back(m);
 | 
			
		||||
        ReplugMonitor();
 | 
			
		||||
        SetResolution(ws->w, ws->h);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -83,6 +83,8 @@ private:
 | 
			
		||||
    bool     preferred;
 | 
			
		||||
  };
 | 
			
		||||
  std::vector<DisplayMode> m_displayModes;
 | 
			
		||||
  DisplayMode m_customMode    = {};
 | 
			
		||||
  bool        m_setCustomMode = false;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
 | 
			
		||||
@@ -92,10 +94,13 @@ public:
 | 
			
		||||
 | 
			
		||||
  bool SetupLGMP(size_t alignSize);
 | 
			
		||||
 | 
			
		||||
  void PopulateDefaultModes(bool setDefaultMode);
 | 
			
		||||
  void InitAdapter();
 | 
			
		||||
  void FinishInit(UINT connectorIndex);
 | 
			
		||||
  void ReplugMonitor();
 | 
			
		||||
  void UnassignSwapChain();
 | 
			
		||||
 | 
			
		||||
  void OnAssignSwapChain();
 | 
			
		||||
  void OnUnassignedSwapChain();
 | 
			
		||||
 | 
			
		||||
  NTSTATUS ParseMonitorDescription(
 | 
			
		||||
    const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs, IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs);
 | 
			
		||||
@@ -104,6 +109,8 @@ public:
 | 
			
		||||
  NTSTATUS MonitorQueryTargetModes(
 | 
			
		||||
    const IDARG_IN_QUERYTARGETMODES* inArgs, IDARG_OUT_QUERYTARGETMODES* outArgs);
 | 
			
		||||
 | 
			
		||||
  void SetResolution(int width, int height);
 | 
			
		||||
 | 
			
		||||
  size_t GetAlignSize()    { return m_alignSize;    }
 | 
			
		||||
  size_t GetMaxFrameSize() { return m_maxFrameSize; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,8 @@ CIndirectMonitorContext::~CIndirectMonitorContext()
 | 
			
		||||
void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent)
 | 
			
		||||
{
 | 
			
		||||
reInit:
 | 
			
		||||
  m_swapChain.reset();
 | 
			
		||||
  UnassignSwapChain();
 | 
			
		||||
 | 
			
		||||
  m_dx11Device = std::make_shared<CD3D11Device>(renderAdapter);
 | 
			
		||||
  if (FAILED(m_dx11Device->Init()))
 | 
			
		||||
  {
 | 
			
		||||
 
 | 
			
		||||
@@ -160,4 +160,17 @@ void CPipeServer::SetCursorPos(uint32_t x, uint32_t y)
 | 
			
		||||
  msg.curorPos.x = x;
 | 
			
		||||
  msg.curorPos.y = y;
 | 
			
		||||
  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 SetCursorPos(uint32_t x, uint32_t y);
 | 
			
		||||
    void SetDisplayMode(uint32_t width, uint32_t height);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern CPipeServer g_pipe;
 | 
			
		||||
@@ -108,6 +108,7 @@ NTSTATUS LGIddMonitorAssignSwapChain(IDDCX_MONITOR monitor, const IDARG_IN_SETSW
 | 
			
		||||
  auto * wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
 | 
			
		||||
  wrapper->context->AssignSwapChain(
 | 
			
		||||
    inArgs->hSwapChain, inArgs->RenderAdapterLuid, inArgs->hNextSurfaceAvailable);
 | 
			
		||||
  wrapper->context->GetDeviceContext()->OnAssignSwapChain();
 | 
			
		||||
  return STATUS_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -115,7 +116,7 @@ NTSTATUS LGIddMonitorUnassignSwapChain(IDDCX_MONITOR monitor)
 | 
			
		||||
{
 | 
			
		||||
  auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
 | 
			
		||||
  wrapper->context->UnassignSwapChain();
 | 
			
		||||
  wrapper->context->GetDeviceContext()->UnassignSwapChain();
 | 
			
		||||
  wrapper->context->GetDeviceContext()->OnUnassignedSwapChain();
 | 
			
		||||
  return STATUS_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -24,33 +24,6 @@
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
{
 | 
			
		||||
  ULONG PrivateDeviceData;  // just a placeholder
 | 
			
		||||
 
 | 
			
		||||
@@ -211,6 +211,10 @@ void CPipeClient::Thread()
 | 
			
		||||
          HandleSetCursorPos(msg);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case LGPipeMsg::SETDISPLAYMODE:
 | 
			
		||||
          HandleSetDisplayMode(msg);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          DEBUG_ERROR("Unknown message type %d", msg.type);
 | 
			
		||||
          break;
 | 
			
		||||
@@ -228,4 +232,17 @@ void CPipeClient::HandleSetCursorPos(const LGPipeMsg& msg)
 | 
			
		||||
{
 | 
			
		||||
  SetActiveDesktop();
 | 
			
		||||
  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 HandleSetCursorPos(const LGPipeMsg& msg);
 | 
			
		||||
  void HandleSetDisplayMode(const LGPipeMsg& msg);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  ~CPipeClient() { DeInit(); }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user