there is only one cursor in screens.

This commit is contained in:
hecomi
2016-11-06 03:30:21 +09:00
parent 9de5064fbe
commit 9e42fb0abf
10 changed files with 128 additions and 69 deletions
@@ -26,54 +26,64 @@ Cursor::~Cursor()
}
void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
void Cursor::UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
{
isVisible_ = frameInfo.PointerPosition.Visible != 0;
x_ = frameInfo.PointerPosition.Position.x;
y_ = frameInfo.PointerPosition.Position.y;
if (frameInfo.LastMouseUpdateTime.QuadPart == 0)
{
return;
}
// TODO: see more information to check where the cursor is.
if (isVisible_)
{
GetMonitorManager()->SetCursorMonitorId(monitor_->GetId());
}
x_ = frameInfo.PointerPosition.Position.x;
y_ = frameInfo.PointerPosition.Position.y;
if (frameInfo.PointerPosition.Visible != 0) {
GetMonitorManager()->SetCursorMonitorId(monitor_->GetId());
timestamp_ = frameInfo.LastMouseUpdateTime;
isVisible_ = frameInfo.PointerPosition.Visible != 0;
}
if (GetMonitorManager()->GetCursorMonitorId() != monitor_->GetId()) {
return;
}
if (frameInfo.PointerShapeBufferSize == 0)
{
return;
}
// Increase the buffer size if needed
if (frameInfo.PointerShapeBufferSize > apiBufferSize_)
{
if (apiBuffer_) delete[] apiBuffer_;
apiBuffer_ = new BYTE[frameInfo.PointerShapeBufferSize];
apiBufferSize_ = frameInfo.PointerShapeBufferSize;
}
if (apiBuffer_ == nullptr) return;
// Increase the buffer size if needed
if (frameInfo.PointerShapeBufferSize > apiBufferSize_)
{
if (apiBuffer_) delete[] apiBuffer_;
apiBuffer_ = new BYTE[frameInfo.PointerShapeBufferSize];
apiBufferSize_ = frameInfo.PointerShapeBufferSize;
}
if (apiBuffer_ == nullptr) return;
// Get information about the mouse pointer if needed
if (frameInfo.PointerShapeBufferSize != 0)
{
UINT bufferSize;
monitor_->GetDeskDupl()->GetFramePointerShape(
frameInfo.PointerShapeBufferSize,
reinterpret_cast<void*>(apiBuffer_),
&bufferSize,
&shapeInfo_);
}
// Get mouse pointer information
UINT bufferSize;
const auto hr = monitor_->GetDeskDupl()->GetFramePointerShape(
frameInfo.PointerShapeBufferSize,
reinterpret_cast<void*>(apiBuffer_),
&bufferSize,
&shapeInfo_);
if (FAILED(hr))
{
delete[] apiBuffer_;
apiBuffer_ = nullptr;
apiBufferSize_ = 0;
}
}
void Cursor::UpdateTexture()
{
// cursor type
const auto cursorType = shapeInfo_.Type;
const bool isMono = cursorType == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME;
const bool isColorMask = cursorType == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR;
const bool isMono = GetType() == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME;
const bool isColorMask = GetType() == DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR;
// Size
const auto w = shapeInfo_.Width;
const auto h = shapeInfo_.Height / (isMono ? 2 : 1);
const auto p = shapeInfo_.Pitch;
const auto w = GetWidth();
const auto h = GetHeight();
const auto p = GetPitch();
// Convert the buffer given by API into BGRA32
const auto bgraBufferSize = w * h * 4;
const UINT bgraBufferSize = w * h * 4;
if (bgraBufferSize > bgra32BufferSize_)
{
if (bgra32Buffer_) delete[] bgra32Buffer_;
@@ -145,10 +155,10 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
if (isMono)
{
for (UINT row = 0; row < h; ++row)
for (int row = 0; row < h; ++row)
{
BYTE mask = 0x80;
for (UINT col = 0; col < w; ++col)
for (int col = 0; col < w; ++col)
{
const int i = row * w + col;
const BYTE andMask = apiBuffer_[col / 8 + row * p] & mask;
@@ -164,9 +174,9 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
{
const auto buffer32 = reinterpret_cast<UINT*>(apiBuffer_);
for (UINT row = 0; row < h; ++row)
for (int row = 0; row < h; ++row)
{
for (UINT col = 0; col < w; ++col)
for (int col = 0; col < w; ++col)
{
const int i = row * w + col;
const int j = row * p / sizeof(UINT) + col;
@@ -195,7 +205,7 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
{
auto output32 = reinterpret_cast<UINT*>(bgra32Buffer_);
const auto buffer32 = reinterpret_cast<UINT*>(apiBuffer_);
for (UINT i = 0; i < w * h; ++i)
for (int i = 0; i < w * h; ++i)
{
output32[i] = buffer32[i];
}
@@ -205,7 +215,7 @@ void Cursor::Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo)
}
void Cursor::UpdateTexture(ID3D11Texture2D* texture)
void Cursor::GetTexture(ID3D11Texture2D* texture)
{
if (bgra32Buffer_ == nullptr) return;
ID3D11DeviceContext* context;
@@ -9,8 +9,9 @@ class Cursor
public:
explicit Cursor(Monitor* monitor);
~Cursor();
void Update(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
void UpdateTexture(ID3D11Texture2D* texture);
void UpdateBuffer(const DXGI_OUTDUPL_FRAME_INFO& frameInfo);
void UpdateTexture();
void GetTexture(ID3D11Texture2D* texture);
bool IsVisible() const;
int GetX() const;
@@ -30,4 +31,5 @@ private:
BYTE* bgra32Buffer_ = nullptr;
UINT bgra32BufferSize_ = 0;
DXGI_OUTDUPL_POINTER_SHAPE_INFO shapeInfo_;
LARGE_INTEGER timestamp_;
};
@@ -77,12 +77,20 @@ HRESULT Monitor::Render(UINT timeout)
const auto hr = deskDupl_->AcquireNextFrame(timeout, &frameInfo, &resource);
if (FAILED(hr))
{
// If any monitor setting has changed (e.g. monitor size has changed),
// it is necessary to re-initialize monitors.
if (hr == DXGI_ERROR_ACCESS_LOST)
{
state_ = State::AccessLost;
}
switch (hr)
{
case DXGI_ERROR_ACCESS_LOST:
// If any monitor setting has changed (e.g. monitor size has changed),
// it is necessary to re-initialize monitors.
state_ = State::AccessLost;
break;
case DXGI_ERROR_WAIT_TIMEOUT:
break;
case DXGI_ERROR_INVALID_CALL:
break;
case E_INVALIDARG:
break;
}
return hr;
}
@@ -94,7 +102,8 @@ HRESULT Monitor::Render(UINT timeout)
context->CopyResource(unityTexture_, texture);
context->Release();
cursor_->Update(frameInfo);
cursor_->UpdateBuffer(frameInfo);
cursor_->UpdateTexture();
resource->Release();
deskDupl_->ReleaseFrame();
@@ -139,9 +148,9 @@ const std::unique_ptr<Cursor>& Monitor::GetCursor()
}
void Monitor::UpdateCursorTexture(ID3D11Texture2D* texture)
void Monitor::GetCursorTexture(ID3D11Texture2D* texture)
{
cursor_->UpdateTexture(texture);
cursor_->GetTexture(texture);
}
@@ -25,7 +25,7 @@ public:
~Monitor();
HRESULT Initialize(IDXGIOutput* output);
HRESULT Render(UINT timeout = 0);
void UpdateCursorTexture(ID3D11Texture2D* texture);
void GetCursorTexture(ID3D11Texture2D* texture);
public:
int GetId() const;
@@ -304,12 +304,12 @@ extern "C"
return -1;
}
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API UpdateCursorTexture(int id, ID3D11Texture2D* texture)
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API GetCursorTexture(int id, ID3D11Texture2D* texture)
{
if (!g_manager) return;
if (auto monitor = g_manager->GetMonitor(id))
{
monitor->UpdateCursorTexture(texture);
monitor->GetCursorTexture(texture);
}
}