mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 07:01:30 +00:00
[idd] clipboard: add direct synchronization
This commit is contained in:
@@ -37,6 +37,7 @@ bool CPipeServer::Init()
|
||||
void CPipeServer::DeInit()
|
||||
{
|
||||
m_endpoint.Stop();
|
||||
m_clipboard.Detach();
|
||||
}
|
||||
|
||||
void CPipeServer::OnPipeConnected()
|
||||
@@ -60,6 +61,11 @@ void CPipeServer::OnPipeConnected()
|
||||
m_endpoint.Send(&m_recoveryRequest, sizeof(m_recoveryRequest));
|
||||
}
|
||||
|
||||
void CPipeServer::OnPipeDisconnected()
|
||||
{
|
||||
m_clipboard.Detach();
|
||||
}
|
||||
|
||||
bool CPipeServer::OnPipeMessage(const void * message, size_t size)
|
||||
{
|
||||
if (size != sizeof(LGPipeMsg))
|
||||
@@ -82,12 +88,90 @@ bool CPipeServer::OnPipeMessage(const void * message, size_t size)
|
||||
HandleRecovery(msg);
|
||||
return true;
|
||||
|
||||
case LGPipeMsg::CLIPBOARD_SETUP:
|
||||
{
|
||||
HANDLE transferred = reinterpret_cast<HANDLE>(
|
||||
static_cast<uintptr_t>(msg.clipboardSetup.handle));
|
||||
HANDLE mapping = transferred;
|
||||
uint64_t epoch = 0;
|
||||
if (transferred &&
|
||||
msg.clipboardSetup.bytes == sizeof(ClipboardMapping))
|
||||
{
|
||||
ClipboardMapping * view = static_cast<ClipboardMapping *>(
|
||||
MapViewOfFile(mapping, FILE_MAP_READ, 0, 0,
|
||||
sizeof(ClipboardMapping)));
|
||||
if (view)
|
||||
{
|
||||
epoch = view->epoch;
|
||||
UnmapViewOfFile(view);
|
||||
}
|
||||
}
|
||||
else if (transferred)
|
||||
{
|
||||
CloseHandle(transferred);
|
||||
mapping = nullptr;
|
||||
}
|
||||
|
||||
// The transferred handle has exactly one owner from this point:
|
||||
// Attach consumes it on both success and failure paths.
|
||||
const bool ready = m_clipboard.Attach(
|
||||
mapping, epoch, false, *this);
|
||||
LGPipeMsg reply = {};
|
||||
reply.size = sizeof(reply);
|
||||
reply.type = LGPipeMsg::CLIPBOARD_READY;
|
||||
reply.clipboardReady.epoch = epoch;
|
||||
reply.clipboardReady.status = ready ? ERROR_SUCCESS : ERROR_INVALID_DATA;
|
||||
m_endpoint.Send(&reply, sizeof(reply));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LGPipeMsg::CLIPBOARD_READY:
|
||||
// READY normally travels IDD to Helper. A failure in the reverse
|
||||
// direction reports that Helper activation failed after IDD attach.
|
||||
if (msg.clipboardReady.status != ERROR_SUCCESS &&
|
||||
msg.clipboardReady.epoch == m_clipboard.Epoch())
|
||||
{
|
||||
m_clipboard.Reset(
|
||||
msg.clipboardReady.epoch, msg.clipboardReady.status);
|
||||
m_clipboard.Detach();
|
||||
}
|
||||
return true;
|
||||
|
||||
case LGPipeMsg::CLIPBOARD_KICK:
|
||||
m_clipboard.Kick(msg.clipboardKick.epoch);
|
||||
return true;
|
||||
|
||||
case LGPipeMsg::CLIPBOARD_RESET:
|
||||
m_clipboard.Reset(
|
||||
msg.clipboardReset.epoch, msg.clipboardReset.reason);
|
||||
return true;
|
||||
|
||||
default:
|
||||
DEBUG_ERROR("Unknown message type %d", msg.type);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CPipeServer::ClipboardKick(uint64_t epoch)
|
||||
{
|
||||
LGPipeMsg msg = {};
|
||||
msg.size = sizeof(msg);
|
||||
msg.type = LGPipeMsg::CLIPBOARD_KICK;
|
||||
msg.clipboardKick.epoch = epoch;
|
||||
msg.clipboardKick.rings = 0;
|
||||
return m_endpoint.Send(&msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void CPipeServer::ClipboardResetPeer(uint64_t epoch, uint32_t reason)
|
||||
{
|
||||
LGPipeMsg msg = {};
|
||||
msg.size = sizeof(msg);
|
||||
msg.type = LGPipeMsg::CLIPBOARD_RESET;
|
||||
msg.clipboardReset.epoch = epoch;
|
||||
msg.clipboardReset.reason = reason;
|
||||
m_endpoint.Send(&msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void CPipeServer::QueueMsgLocked(const LGPipeMsg & msg)
|
||||
{
|
||||
for (LGPipeMsg & queued : m_queue)
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
#include <vector>
|
||||
|
||||
#include "CPipeEndpoint.h"
|
||||
#include "CClipboardChannel.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "PipeMsg.h"
|
||||
|
||||
class CDeviceContext;
|
||||
|
||||
class CPipeServer : private IPipeEndpointHandler
|
||||
class CPipeServer : private IPipeEndpointHandler,
|
||||
public IClipboardChannelDoorbell
|
||||
{
|
||||
public:
|
||||
using RecoveryHandler = void (*)(void * opaque,
|
||||
@@ -40,6 +42,7 @@ class CPipeServer : private IPipeEndpointHandler
|
||||
|
||||
private:
|
||||
CPipeEndpoint m_endpoint;
|
||||
CClipboardChannel m_clipboard;
|
||||
CSRWLock m_queueLock;
|
||||
std::vector<LGPipeMsg> m_queue;
|
||||
bool m_recoveryValid = false;
|
||||
@@ -60,6 +63,7 @@ class CPipeServer : private IPipeEndpointHandler
|
||||
void HandleRecovery(const LGPipeMsg & msg);
|
||||
|
||||
void OnPipeConnected() override;
|
||||
void OnPipeDisconnected() override;
|
||||
bool OnPipeMessage(const void * message, size_t size) override;
|
||||
|
||||
public:
|
||||
@@ -80,6 +84,10 @@ class CPipeServer : private IPipeEndpointHandler
|
||||
uint32_t requiredSizeMiB);
|
||||
bool SetRecovery(void * owner, uint64_t route,
|
||||
uint64_t session, uint32_t serial, bool active);
|
||||
|
||||
CClipboardChannel& Clipboard() { return m_clipboard; }
|
||||
bool ClipboardKick(uint64_t epoch) override;
|
||||
void ClipboardResetPeer(uint64_t epoch, uint32_t reason) override;
|
||||
};
|
||||
|
||||
extern CPipeServer g_pipe;
|
||||
|
||||
Reference in New Issue
Block a user