there is only one cursor in screens.
This commit is contained in:
Binary file not shown.
@@ -54,14 +54,15 @@ public class Cursor : MonoBehaviour
|
||||
}
|
||||
|
||||
var cursorTexture = textures_[scale];
|
||||
monitor.UpdateCursorTexture(cursorTexture.GetNativeTexturePtr());
|
||||
monitor.GetCursorTexture(cursorTexture.GetNativeTexturePtr());
|
||||
uddTexture_.material.SetTexture("_CursorTex", cursorTexture);
|
||||
}
|
||||
|
||||
void UpdateMaterial()
|
||||
{
|
||||
var x = (float)monitor.cursorX / monitor.width;
|
||||
var y = (float)monitor.cursorY / monitor.height;
|
||||
Debug.Log(monitor.isCursorVisible);
|
||||
var x = monitor.isCursorVisible ? (float)monitor.cursorX / monitor.width : -9999f;
|
||||
var y = monitor.isCursorVisible ? (float)monitor.cursorY / monitor.height : -9999f;
|
||||
var w = (float)monitor.cursorShapeWidth / monitor.width;
|
||||
var h = (float)monitor.cursorShapeHeight / monitor.height;
|
||||
uddTexture_.material.SetVector("_CursorPositionScale", new Vector4(x, y, w, h));
|
||||
|
||||
@@ -98,7 +98,7 @@ public static class Lib
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern CursorShapeType GetCursorShapeType(int id);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern void UpdateCursorTexture(int id, System.IntPtr ptr);
|
||||
public static extern void GetCursorTexture(int id, System.IntPtr ptr);
|
||||
[DllImport("uDesktopDuplication")]
|
||||
public static extern int SetTexturePtr(int id, IntPtr ptr);
|
||||
|
||||
|
||||
@@ -12,7 +12,17 @@ public class Manager : MonoBehaviour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance_) return instance_;
|
||||
if (instance_) {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
var manager = FindObjectOfType<Manager>();
|
||||
if (manager) {
|
||||
manager.Awake();
|
||||
instance_ = manager;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
var go = new GameObject("uDesktopDuplicationManager");
|
||||
return go.AddComponent<Manager>();
|
||||
}
|
||||
@@ -81,12 +91,19 @@ public class Manager : MonoBehaviour
|
||||
UpdateMessage();
|
||||
}
|
||||
|
||||
[ContextMenu("Reinitialize")]
|
||||
void Reinitialize()
|
||||
{
|
||||
Lib.Reinitialize();
|
||||
}
|
||||
|
||||
void ReinitializeIfNeeded()
|
||||
{
|
||||
for (int i = 0; i < monitors.Count; ++i) {
|
||||
var monitor = monitors[i];
|
||||
if (monitor.state == MonitorState.AccessLost ||
|
||||
monitor.state == MonitorState.AccessDenied) {
|
||||
monitor.state == MonitorState.AccessDenied ||
|
||||
monitor.state == MonitorState.SessionDisconnected) {
|
||||
if (!shouldReinitialize) {
|
||||
shouldReinitialize = true;
|
||||
reinitializationTimer = 0f;
|
||||
@@ -97,7 +114,7 @@ public class Manager : MonoBehaviour
|
||||
|
||||
if (shouldReinitialize) {
|
||||
if (reinitializationTimer > retryReinitializationDuration) {
|
||||
Lib.Reinitialize();
|
||||
Reinitialize();
|
||||
shouldReinitialize = false;
|
||||
}
|
||||
reinitializationTimer += Time.deltaTime;
|
||||
@@ -110,8 +127,7 @@ public class Manager : MonoBehaviour
|
||||
while (message != Message.None) {
|
||||
switch (message) {
|
||||
case Message.Reinitialized:
|
||||
Debug.Log("Reinitialize");
|
||||
Reinitialize();
|
||||
ReinitializeMonitors();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -141,7 +157,7 @@ public class Manager : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
void Reinitialize()
|
||||
void ReinitializeMonitors()
|
||||
{
|
||||
for (int i = 0; i < monitorCount; ++i) {
|
||||
if (i == monitors.Count) {
|
||||
|
||||
@@ -8,6 +8,27 @@ public class Monitor
|
||||
public Monitor(int id)
|
||||
{
|
||||
this.id = id;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case MonitorState.InvalidArg:
|
||||
Debug.LogErrorFormat("[{0}:{1}] Invalid.", id, name);
|
||||
break;
|
||||
case MonitorState.AccessDenied:
|
||||
Debug.LogErrorFormat("[{0}:{1}] Access Denied.", id, name);
|
||||
break;
|
||||
case MonitorState.Unsupported:
|
||||
Debug.LogErrorFormat("[{0}:{1}] Unsupported.", id, name);
|
||||
break;
|
||||
case MonitorState.SessionDisconnected:
|
||||
Debug.LogErrorFormat("[{0}:{1}] Disconnected.", id, name);
|
||||
break;
|
||||
case MonitorState.NotSet:
|
||||
Debug.LogErrorFormat("[{0}:{1}] Something wrong.", id, name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public int id
|
||||
@@ -150,9 +171,9 @@ public class Monitor
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCursorTexture(System.IntPtr ptr)
|
||||
public void GetCursorTexture(System.IntPtr ptr)
|
||||
{
|
||||
Lib.UpdateCursorTexture(id, ptr);
|
||||
Lib.GetCursorTexture(id, ptr);
|
||||
}
|
||||
|
||||
void CreateTexture()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user