[c-host] dxgi: use low level mouse input by default

This is known to prevent cursor updates on the secure desktop
(UAC) but DXGI DD does not provide us with the real mouse
coordinates when applications have 'captured' the cursor.
This commit is contained in:
Geoffrey McRae 2020-01-29 21:58:39 +11:00
parent e30b54ddb2
commit dc4d820666

View file

@ -25,6 +25,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "common/locking.h"
#include "common/event.h"
#include "windows/mousehook.h"
#include <assert.h>
#include <dxgi.h>
#include <d3d11.h>
@ -82,6 +84,9 @@ struct iface
unsigned int stride;
CaptureFormat format;
LG_Lock pointerLock;
bool decouplePointer;
int hotspotX , hotspotY;
int lastPointerX, lastPointerY;
bool lastPointerVisible;
};
@ -96,6 +101,28 @@ static CaptureResult dxgi_releaseFrame();
// implementation
static void on_mouseMove(int x, int y)
{
LG_LOCK(this->pointerLock);
x -= this->hotspotX;
y -= this->hotspotY;
this->lastPointerX = x;
this->lastPointerY = y;
CapturePointer pointer =
{
.positionUpdate = true,
.visible = this->lastPointerVisible,
.x = x,
.y = y
};
this->postPointerBufferFn(pointer);
LG_UNLOCK(this->pointerLock);
}
static const char * dxgi_getName()
{
return "DXGI";
@ -133,6 +160,14 @@ static void dxgi_initOptions()
.type = OPTION_TYPE_BOOL,
.value.x_bool = false
},
{
.module = "dxgi",
.name = "decouplePointer",
.description = "Use a low level hook to obtain cursor position information",
.type = OPTION_TYPE_BOOL,
.value.x_bool = true
},
{0}
};
@ -161,10 +196,18 @@ static bool dxgi_create(CaptureGetPointerBuffer getPointerBufferFn, CapturePostP
if (this->maxTextures <= 0)
this->maxTextures = 1;
this->useAcquireLock = option_get_bool("dxgi", "useAcquireLock");
this->useAcquireLock = option_get_bool("dxgi", "useAcquireLock" );
this->decouplePointer = option_get_bool("dxgi", "decouplePointer");
this->texture = calloc(sizeof(struct Texture), this->maxTextures);
this->getPointerBufferFn = getPointerBufferFn;
this->postPointerBufferFn = postPointerBufferFn;
LG_LOCK_INIT(this->pointerLock);
if (this->decouplePointer)
mouseHook_install(on_mouseMove);
return true;
}
@ -529,6 +572,8 @@ static bool dxgi_deinit()
{
assert(this);
mouseHook_remove();
for(int i = 0; i < this->maxTextures; ++i)
{
this->texture[i].state = TEXTURE_STATE_UNUSED;
@ -712,22 +757,20 @@ static CaptureResult dxgi_capture()
frameInfo.PointerPosition.Visible != this->lastPointerVisible
)
{
LG_LOCK(this->pointerLock);
/* the pointer position is invalid if the pointer is not visible */
if (frameInfo.PointerPosition.Visible)
if (!this->decouplePointer && frameInfo.PointerPosition.Visible)
{
pointer.positionUpdate = true;
pointer.x =
this->lastPointerX =
frameInfo.PointerPosition.Position.x;
pointer.y =
this->lastPointerY =
frameInfo.PointerPosition.Position.y;
this->lastPointerX = frameInfo.PointerPosition.Position.x;
this->lastPointerY = frameInfo.PointerPosition.Position.y;
}
pointer.visible =
this->lastPointerVisible =
frameInfo.PointerPosition.Visible;
this->lastPointerVisible = frameInfo.PointerPosition.Visible;
postPointer = true;
LG_UNLOCK(this->pointerLock);
}
}
@ -758,6 +801,12 @@ static CaptureResult dxgi_capture()
return CAPTURE_RESULT_ERROR;
}
// needed in decouple mode
LG_LOCK(this->pointerLock);
this->hotspotX = shapeInfo.HotSpot.x;
this->hotspotY = shapeInfo.HotSpot.y;
LG_UNLOCK(this->pointerLock);
pointer.shapeUpdate = true;
pointer.width = shapeInfo.Width;
pointer.height = shapeInfo.Height;
@ -768,7 +817,12 @@ static CaptureResult dxgi_capture()
// post back the pointer information
if (postPointer)
{
LG_LOCK(this->pointerLock);
pointer.visible = this->lastPointerVisible;
this->postPointerBufferFn(pointer);
LG_UNLOCK(this->pointerLock);
}
return CAPTURE_RESULT_OK;
}