diff --git a/c-host/platform/Windows/capture/DXGI/src/dxgi.c b/c-host/platform/Windows/capture/DXGI/src/dxgi.c index d1c9404c..94742714 100644 --- a/c-host/platform/Windows/capture/DXGI/src/dxgi.c +++ b/c-host/platform/Windows/capture/DXGI/src/dxgi.c @@ -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 #include #include @@ -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; }