mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 08:41:31 +00:00
[idd] ipc: connect LGInput to LGIdd
Move the reusable named-pipe endpoint and shared support code into the LGCommon static library. Run a dedicated server in LGIdd and a reconnecting client in LGInput, with device-lifecycle handling and report framing. Refactor the helper pipe to use the same endpoint implementation.
This commit is contained in:
@@ -114,51 +114,16 @@ bool CPipeClient::Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_signal.Attach(CreateEvent(NULL, TRUE, FALSE, NULL));
|
||||
if (!m_signal.IsValid())
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "Failed to create pipe signal event");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
m_thread.Attach(CreateThread(
|
||||
NULL,
|
||||
0,
|
||||
_pipeThread,
|
||||
(LPVOID)this,
|
||||
0,
|
||||
NULL));
|
||||
|
||||
if (!m_thread.IsValid())
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "Failed to create the pipe thread");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
m_endpoint.SetHandler(this);
|
||||
return m_endpoint.Start(
|
||||
LG_PIPE_NAME,
|
||||
CPipeEndpoint::Mode::Client,
|
||||
sizeof(LGPipeMsg));
|
||||
}
|
||||
|
||||
void CPipeClient::DeInit()
|
||||
{
|
||||
m_connected = false;
|
||||
m_running = false;
|
||||
if (m_signal.IsValid())
|
||||
SetEvent(m_signal.Get());
|
||||
|
||||
if (m_thread.IsValid())
|
||||
{
|
||||
WaitForSingleObject(m_thread.Get(), INFINITE);
|
||||
m_thread.Close();
|
||||
}
|
||||
|
||||
if (m_pipe.IsValid())
|
||||
{
|
||||
FlushFileBuffers(m_pipe.Get());
|
||||
m_pipe.Close();
|
||||
}
|
||||
|
||||
m_signal.Close();
|
||||
m_endpoint.Stop();
|
||||
}
|
||||
|
||||
bool CPipeClient::IsLGIddDeviceAttached()
|
||||
@@ -228,28 +193,12 @@ void CPipeClient::SetActiveDesktop()
|
||||
|
||||
void CPipeClient::WriteMsg(const LGPipeMsg& msg)
|
||||
{
|
||||
DWORD written;
|
||||
if (!WriteFile(m_pipe.Get(), &msg, sizeof(msg), &written, NULL))
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_BROKEN_PIPE)
|
||||
{
|
||||
DEBUG_WARN_HR(err, "Client disconnected, failed to write");
|
||||
m_connected = false;
|
||||
SetEvent(m_signal.Get());
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_WARN_HR(err, "WriteFile failed on the pipe");
|
||||
return;
|
||||
}
|
||||
|
||||
FlushFileBuffers(m_pipe.Get());
|
||||
m_endpoint.Send(&msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void CPipeClient::ReloadSettings()
|
||||
{
|
||||
if (!m_connected)
|
||||
if (!m_endpoint.IsConnected())
|
||||
return;
|
||||
|
||||
LGPipeMsg msg = {};
|
||||
@@ -258,6 +207,14 @@ void CPipeClient::ReloadSettings()
|
||||
WriteMsg(msg);
|
||||
}
|
||||
|
||||
bool CPipeClient::ShouldReconnect()
|
||||
{
|
||||
const bool attached = IsLGIddDeviceAttached();
|
||||
if (!attached)
|
||||
DEBUG_INFO("Looking Glass Indirect Display Device was removed");
|
||||
return attached;
|
||||
}
|
||||
|
||||
bool CPipeClient::EnsureOnlyDisplayLocked()
|
||||
{
|
||||
std::vector<DisplayState> displays;
|
||||
@@ -372,124 +329,37 @@ bool CPipeClient::EnsureOnlyDisplay()
|
||||
return result;
|
||||
}
|
||||
|
||||
void CPipeClient::Thread()
|
||||
bool CPipeClient::OnPipeMessage(const void * message, size_t size)
|
||||
{
|
||||
DEBUG_INFO("Pipe thread started");
|
||||
if (size != sizeof(LGPipeMsg))
|
||||
return false;
|
||||
|
||||
HandleT<EventTraits> ioEvent(CreateEvent(NULL, TRUE, FALSE, NULL));
|
||||
if (!ioEvent.IsValid())
|
||||
const LGPipeMsg & msg = *static_cast<const LGPipeMsg *>(message);
|
||||
if (msg.size != sizeof(msg))
|
||||
return false;
|
||||
|
||||
switch (msg.type)
|
||||
{
|
||||
DEBUG_ERROR("Can't create event for overlapped I/O!");
|
||||
WaitForSingleObject(m_signal.Get(), 5000);
|
||||
return;
|
||||
case LGPipeMsg::SETCURSORPOS:
|
||||
HandleSetCursorPos(msg);
|
||||
return true;
|
||||
|
||||
case LGPipeMsg::SETDISPLAYMODE:
|
||||
HandleSetDisplayMode(msg);
|
||||
return true;
|
||||
|
||||
case LGPipeMsg::GPUSTATUS:
|
||||
HandleGPUStatus(msg);
|
||||
return true;
|
||||
|
||||
case LGPipeMsg::RESOLUTIONREJECTED:
|
||||
HandleResolutionRejected(msg);
|
||||
return true;
|
||||
|
||||
default:
|
||||
DEBUG_ERROR("Unknown message type %d", msg.type);
|
||||
return true;
|
||||
}
|
||||
|
||||
while (m_running)
|
||||
{
|
||||
if (!IsLGIddDeviceAttached())
|
||||
{
|
||||
m_running = false;
|
||||
DEBUG_ERROR("Device is no longer available, shutting down");
|
||||
break;
|
||||
}
|
||||
|
||||
m_pipe.Attach(CreateFile(
|
||||
TEXT(LG_PIPE_NAME),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
NULL
|
||||
));
|
||||
|
||||
if (!m_pipe.IsValid())
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "Failed to open the named pipe");
|
||||
WaitForSingleObject(m_signal.Get(), 5000);
|
||||
continue;
|
||||
}
|
||||
|
||||
m_connected = true;
|
||||
DEBUG_INFO("Pipe connected");
|
||||
|
||||
while (m_running && m_connected)
|
||||
{
|
||||
LGPipeMsg msg;
|
||||
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = ioEvent.Get();
|
||||
|
||||
if (!ReadFile(m_pipe.Get(), &msg, sizeof(msg), NULL, &overlapped))
|
||||
{
|
||||
DWORD dwError = GetLastError();
|
||||
if (dwError != ERROR_IO_PENDING)
|
||||
{
|
||||
DEBUG_ERROR_HR(dwError, "ReadFile Failed");
|
||||
break;
|
||||
}
|
||||
|
||||
HANDLE hWait[] = { ioEvent.Get(), m_signal.Get() };
|
||||
switch (WaitForMultipleObjects(2, hWait, FALSE, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
DEBUG_INFO("I/O interrupted by signal");
|
||||
CancelIo(m_pipe.Get());
|
||||
WaitForSingleObject(ioEvent.Get(), INFINITE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD bytesRead;
|
||||
GetOverlappedResult(m_pipe.Get(), &overlapped, &bytesRead, TRUE);
|
||||
|
||||
if (bytesRead != sizeof(msg))
|
||||
{
|
||||
DEBUG_ERROR("Corrupted data, expected %lld bytes, read %lld bytes", sizeof msg, bytesRead);
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg.size != sizeof(msg))
|
||||
{
|
||||
DEBUG_ERROR("Corrupted data, expected %lld bytes, actual message size: %lld bytes", sizeof msg, msg.size);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (msg.type)
|
||||
{
|
||||
case LGPipeMsg::SETCURSORPOS:
|
||||
HandleSetCursorPos(msg);
|
||||
break;
|
||||
|
||||
case LGPipeMsg::SETDISPLAYMODE:
|
||||
HandleSetDisplayMode(msg);
|
||||
break;
|
||||
|
||||
case LGPipeMsg::GPUSTATUS:
|
||||
HandleGPUStatus(msg);
|
||||
break;
|
||||
|
||||
case LGPipeMsg::RESOLUTIONREJECTED:
|
||||
HandleResolutionRejected(msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_ERROR("Unknown message type %d", msg.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pipe.Close();
|
||||
m_connected = false;
|
||||
DEBUG_INFO("Pipe closed");
|
||||
|
||||
if (m_running)
|
||||
ResetEvent(m_signal.Get());
|
||||
}
|
||||
|
||||
DEBUG_INFO("Pipe thread shutdown");
|
||||
}
|
||||
|
||||
void CPipeClient::HandleSetCursorPos(const LGPipeMsg& msg)
|
||||
|
||||
@@ -22,28 +22,16 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#include "CPipeEndpoint.h"
|
||||
#include "PipeMsg.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace Microsoft::WRL::Wrappers::HandleTraits;
|
||||
|
||||
class CPipeClient
|
||||
class CPipeClient : private IPipeEndpointHandler
|
||||
{
|
||||
private:
|
||||
HandleT<HANDLETraits> m_pipe;
|
||||
HandleT<HANDLENullTraits> m_thread;
|
||||
HandleT<EventTraits> m_signal;
|
||||
|
||||
bool m_running = false;
|
||||
bool m_connected = false;
|
||||
CPipeEndpoint m_endpoint;
|
||||
SRWLOCK m_displayLock = SRWLOCK_INIT;
|
||||
|
||||
static DWORD WINAPI _pipeThread(LPVOID lpParam) { ((CPipeClient*)lpParam)->Thread(); return 0; }
|
||||
void Thread();
|
||||
|
||||
void WriteMsg(const LGPipeMsg& msg);
|
||||
|
||||
void SetActiveDesktop();
|
||||
@@ -55,6 +43,9 @@ private:
|
||||
void HandleGPUStatus(const LGPipeMsg& msg);
|
||||
void HandleResolutionRejected(const LGPipeMsg& msg);
|
||||
|
||||
bool ShouldReconnect() override;
|
||||
bool OnPipeMessage(const void * message, size_t size) override;
|
||||
|
||||
public:
|
||||
~CPipeClient() { DeInit(); }
|
||||
|
||||
@@ -62,7 +53,7 @@ public:
|
||||
|
||||
bool Init();
|
||||
void DeInit();
|
||||
bool IsRunning() { return m_running; }
|
||||
bool IsRunning() { return m_endpoint.IsRunning(); }
|
||||
|
||||
void ReloadSettings();
|
||||
bool EnsureOnlyDisplay();
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
@@ -127,12 +127,11 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CONSOLE;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>Default</LanguageStandard_C>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -161,7 +160,6 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>Default</LanguageStandard_C>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)LGCommon;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -181,8 +179,16 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
<InputResourceManifests>$(ProjectDir)HighDPI.manifest</InputResourceManifests>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(SolutionDir)LGCommon\*.cpp" />
|
||||
<ClCompile Include="CButton.cpp" />
|
||||
<ClCompile Include="CCheckbox.cpp" />
|
||||
<ClCompile Include="CConfigWindow.cpp" />
|
||||
@@ -199,7 +205,6 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
<ClCompile Include="UIHelpers.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="$(SolutionDir)LGCommon\*.h" />
|
||||
<ClInclude Include="CButton.h" />
|
||||
<ClInclude Include="CCheckbox.h" />
|
||||
<ClInclude Include="CConfigWindow.h" />
|
||||
@@ -224,6 +229,11 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
<ItemGroup>
|
||||
<Manifest Include="HighDPI.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LGCommon\LGCommon.vcxproj">
|
||||
<Project>{acb90e34-01ca-4b86-813b-3d20904994c6}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
<Target Name="GenerateVersionInfo" BeforeTargets="ClCompile">
|
||||
@@ -251,4 +261,4 @@ copy /Y "$(ProjectDir)VERSION" "$(SolutionDir)$(Platform)\$(Configuration)\LGIdd
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\MSBuilder.Git.0.3.0\build\MSBuilder.Git.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSBuilder.Git.0.3.0\build\MSBuilder.Git.props'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(SolutionDir)LGCommon\*.cpp" />
|
||||
<ClCompile Include="CPipeClient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -60,7 +59,6 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="$(SolutionDir)LGCommon\*.h" />
|
||||
<ClInclude Include="CPipeClient.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -115,4 +113,4 @@
|
||||
<ItemGroup>
|
||||
<Manifest Include="HighDPI.manifest" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user