[all] fix missing cursor when client reconnects

This commit is contained in:
Geoffrey McRae 2019-05-28 14:06:15 +10:00
parent b31e8e1cee
commit 3d426ccef8
6 changed files with 70 additions and 32 deletions

View File

@ -1 +1 @@
B1-rc3-4-gf0923c4ed7+1 B1-rc3-5-gb31e8e1cee+1

View File

@ -806,11 +806,8 @@ static CaptureResult dxgi_getPointer(CapturePointer * pointer)
assert(this); assert(this);
assert(this->initialized); assert(this->initialized);
if (!os_waitEvent(this->pointerEvent, TIMEOUT_INFINITE)) if (!os_waitEvent(this->pointerEvent, 1000))
{ return CAPTURE_RESULT_TIMEOUT;
DEBUG_ERROR("Failed to wait on the pointer event");
return CAPTURE_RESULT_ERROR;
}
if (this->stop) if (this->stop)
return CAPTURE_RESULT_REINIT; return CAPTURE_RESULT_REINIT;

View File

@ -277,11 +277,8 @@ static CaptureResult nvfbc_getPointer(CapturePointer * pointer)
{ {
osEventHandle * events[2]; osEventHandle * events[2];
memcpy(&events, &this->cursorEvents, sizeof(osEventHandle *) * 2); memcpy(&events, &this->cursorEvents, sizeof(osEventHandle *) * 2);
if (!os_waitEvents(events, this->seperateCursor ? 2 : 1, false, TIMEOUT_INFINITE)) if (!os_waitEvents(events, this->seperateCursor ? 2 : 1, false, 1000))
{ return CAPTURE_RESULT_TIMEOUT;
DEBUG_ERROR("Failed to wait on the cursor events");
return CAPTURE_RESULT_ERROR;
}
if (this->stop) if (this->stop)
return CAPTURE_RESULT_REINIT; return CAPTURE_RESULT_REINIT;

View File

@ -38,6 +38,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
struct app struct app
{ {
unsigned int clientInstance;
KVMFRHeader * shmHeader; KVMFRHeader * shmHeader;
uint8_t * pointerData; uint8_t * pointerData;
unsigned int pointerDataSize; unsigned int pointerDataSize;
@ -63,25 +65,50 @@ static int pointerThread(void * opaque)
DEBUG_INFO("Pointer thread started"); DEBUG_INFO("Pointer thread started");
volatile KVMFRCursor * ci = &(app.shmHeader->cursor); volatile KVMFRCursor * ci = &(app.shmHeader->cursor);
uint8_t flags;
uint8_t flags;
bool pointerValid = false;
bool shapeValid = false;
unsigned int clientInstance = 0;
CapturePointer pointer = { 0 };
while(app.running) while(app.running)
{ {
CaptureResult result; bool resend = false;
CapturePointer pointer = { 0 }; switch(app.iface->getPointer(&pointer))
result = app.iface->getPointer(&pointer);
if (result == CAPTURE_RESULT_REINIT)
{ {
app.reinit = true; case CAPTURE_RESULT_OK:
break; {
pointerValid = true;
break;
}
case CAPTURE_RESULT_REINIT:
{
app.reinit = true;
break;
}
case CAPTURE_RESULT_ERROR:
{
DEBUG_ERROR("Failed to get the pointer");
break;
}
case CAPTURE_RESULT_TIMEOUT:
{
// if the pointer is valid and the client has restarted, send it
if (pointerValid && clientInstance != app.clientInstance)
{
resend = true;
break;
}
continue;
}
} }
if (result == CAPTURE_RESULT_ERROR) clientInstance = app.clientInstance;
{
DEBUG_ERROR("Failed to get the pointer");
break;
}
// wait for the client to finish with the previous update // wait for the client to finish with the previous update
while((ci->flags & ~KVMFR_CURSOR_FLAG_UPDATE) != 0 && app.running) while((ci->flags & ~KVMFR_CURSOR_FLAG_UPDATE) != 0 && app.running)
@ -95,7 +122,7 @@ static int pointerThread(void * opaque)
flags |= KVMFR_CURSOR_FLAG_VISIBLE; flags |= KVMFR_CURSOR_FLAG_VISIBLE;
// if we have shape data // if we have shape data
if (pointer.shapeUpdate) if (pointer.shapeUpdate || (shapeValid && resend))
{ {
switch(pointer.format) switch(pointer.format)
{ {
@ -112,6 +139,7 @@ static int pointerThread(void * opaque)
ci->pitch = pointer.pitch; ci->pitch = pointer.pitch;
ci->dataPos = app.pointerOffset; ci->dataPos = app.pointerOffset;
++ci->version; ++ci->version;
shapeValid = true;
flags |= KVMFR_CURSOR_FLAG_SHAPE; flags |= KVMFR_CURSOR_FLAG_SHAPE;
} }
@ -367,7 +395,11 @@ int app_main(int argc, char * argv[])
while(app.running) while(app.running)
{ {
INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART)); if (INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART)) & KVMFR_HEADER_FLAG_RESTART)
{
DEBUG_INFO("Client restarted");
++app.clientInstance;
}
if (app.reinit && !captureRestart()) if (app.reinit && !captureRestart())
{ {

View File

@ -85,6 +85,8 @@ struct Inst
float screenScaleX, screenScaleY; float screenScaleX, screenScaleY;
bool useNearest; bool useNearest;
bool cursorVisible;
int cursorX , cursorY;
float mouseWidth , mouseHeight; float mouseWidth , mouseHeight;
float mouseScaleX, mouseScaleY; float mouseScaleX, mouseScaleY;
@ -249,6 +251,13 @@ void egl_on_resize(void * opaque, const int width, const int height, const LG_Re
this->splashRatio = (float)width / (float)height; this->splashRatio = (float)width / (float)height;
this->screenScaleX = 1.0f / width; this->screenScaleX = 1.0f / width;
this->screenScaleY = 1.0f / height; this->screenScaleY = 1.0f / height;
egl_cursor_set_state(
this->cursor,
this->cursorVisible,
(((float)this->cursorX * this->mouseScaleX) - 1.0f) * this->scaleX,
(((float)this->cursorY * this->mouseScaleY) - 1.0f) * this->scaleY
);
} }
bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data) bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data)
@ -270,15 +279,18 @@ bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int
return true; return true;
} }
bool egl_on_mouse_event(void * opaque, const bool visible , const int x, const int y) bool egl_on_mouse_event(void * opaque, const bool visible, const int x, const int y)
{ {
struct Inst * this = (struct Inst *)opaque; struct Inst * this = (struct Inst *)opaque;
this->cursorVisible = visible;
this->cursorX = x;
this->cursorY = y;
egl_cursor_set_state( egl_cursor_set_state(
this->cursor, this->cursor,
visible, this->cursorVisible,
(((float)x * this->mouseScaleX) - 1.0f) * this->scaleX, (((float)this->cursorX * this->mouseScaleX) - 1.0f) * this->scaleX,
(((float)y * this->mouseScaleY) - 1.0f) * this->scaleY (((float)this->cursorY * this->mouseScaleY) - 1.0f) * this->scaleY
); );
return true; return true;

View File

@ -19,8 +19,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#pragma once #pragma once
#if defined(__GCC__) || defined(__GNUC__) #if defined(__GCC__) || defined(__GNUC__)
#define INTERLOCKED_AND8 __sync_and_and_fetch #define INTERLOCKED_AND8 __sync_fetch_and_and
#define INTERLOCKED_OR8 __sync_or_and_fetch #define INTERLOCKED_OR8 __sync_fetch_and_or
#else #else
#define INTERLOCKED_OR8 InterlockedOr8 #define INTERLOCKED_OR8 InterlockedOr8
#define INTERLOCKED_AND8 InterlockedAnd8 #define INTERLOCKED_AND8 InterlockedAnd8