mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 14:21:57 +00:00
[client] use SDL_SetEventFilter for better mouse performance
This partially resolves lag issues on hosts running the amdgpu driver. If mouse caputure is enable the lag issue returns, this is because SDL calls `XSync` in `X11_WarpMouse` and `X11_WarpMouseGlobal`, if these calls are removed all input lag issues dissapear. This issue has been reported to SDL as the calls to `XSync` are not required per the xlib documentation.
This commit is contained in:
parent
3d9d275d61
commit
37ea662998
1 changed files with 198 additions and 195 deletions
393
client/main.c
393
client/main.c
|
@ -177,7 +177,7 @@ static inline void updatePositionInfo()
|
||||||
state.lgr->on_resize(state.lgrData, w, h, state.dstRect);
|
state.lgr->on_resize(state.lgrData, w, h, state.dstRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mainThread()
|
int renderThread(void * unused)
|
||||||
{
|
{
|
||||||
while(state.running)
|
while(state.running)
|
||||||
{
|
{
|
||||||
|
@ -189,6 +189,8 @@ void mainThread()
|
||||||
else
|
else
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cursorThread(void * unused)
|
int cursorThread(void * unused)
|
||||||
|
@ -418,205 +420,191 @@ static inline const uint32_t mapScancode(SDL_Scancode scancode)
|
||||||
return ps2;
|
return ps2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int eventThread(void * arg)
|
struct eventState
|
||||||
{
|
{
|
||||||
bool serverMode = false;
|
bool serverMode;
|
||||||
bool realignGuest = true;
|
bool realignGuest;
|
||||||
bool keyDown[SDL_NUM_SCANCODES];
|
bool keyDown[SDL_NUM_SCANCODES];
|
||||||
|
};
|
||||||
|
|
||||||
memset(keyDown, 0, sizeof(keyDown));
|
int eventFilter(void * userdata, SDL_Event * event)
|
||||||
|
{
|
||||||
|
static bool serverMode = false;
|
||||||
|
static bool realignGuest = true;
|
||||||
|
static bool keyDown[SDL_NUM_SCANCODES] = {false};
|
||||||
|
|
||||||
// ensure mouse acceleration is identical in server mode
|
if (event->type == SDL_WINDOWEVENT)
|
||||||
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);
|
|
||||||
|
|
||||||
while(state.running)
|
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
switch(event->window.event)
|
||||||
if (!SDL_PollEvent(&event))
|
|
||||||
{
|
{
|
||||||
usleep(1000);
|
case SDL_WINDOWEVENT_ENTER:
|
||||||
continue;
|
realignGuest = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
|
updatePositionInfo();
|
||||||
|
realignGuest = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params.useSpice)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch(event->type)
|
||||||
|
{
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!serverMode && (
|
||||||
|
event->motion.x < state.dstRect.x ||
|
||||||
|
event->motion.x > state.dstRect.x + state.dstRect.w ||
|
||||||
|
event->motion.y < state.dstRect.y ||
|
||||||
|
event->motion.y > state.dstRect.y + state.dstRect.h
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
realignGuest = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
if (realignGuest && state.haveCursorPos)
|
||||||
|
{
|
||||||
|
x = event->motion.x - state.dstRect.x;
|
||||||
|
y = event->motion.y - state.dstRect.y;
|
||||||
|
if (params.scaleMouseInput)
|
||||||
|
{
|
||||||
|
x = (float)x * state.scaleX;
|
||||||
|
y = (float)y * state.scaleY;
|
||||||
|
}
|
||||||
|
x -= state.cursor.x;
|
||||||
|
y -= state.cursor.y;
|
||||||
|
realignGuest = false;
|
||||||
|
|
||||||
|
if (!spice_mouse_motion(x, y))
|
||||||
|
DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = event->motion.xrel;
|
||||||
|
y = event->motion.yrel;
|
||||||
|
if (x != 0 || y != 0)
|
||||||
|
{
|
||||||
|
if (params.scaleMouseInput)
|
||||||
|
{
|
||||||
|
x = (float)x * state.scaleX;
|
||||||
|
y = (float)y * state.scaleY;
|
||||||
|
}
|
||||||
|
if (!spice_mouse_motion(x, y))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(event.type)
|
case SDL_KEYDOWN:
|
||||||
{
|
{
|
||||||
case SDL_QUIT:
|
SDL_Scancode sc = event->key.keysym.scancode;
|
||||||
if (!params.ignoreQuit)
|
if (sc == SDL_SCANCODE_SCROLLLOCK)
|
||||||
state.running = false;
|
{
|
||||||
|
if (event->key.repeat)
|
||||||
|
break;
|
||||||
|
|
||||||
|
serverMode = !serverMode;
|
||||||
|
spice_mouse_mode(serverMode);
|
||||||
|
SDL_SetRelativeMouseMode(serverMode);
|
||||||
|
DEBUG_INFO("Server Mode: %s", serverMode ? "on" : "off");
|
||||||
|
|
||||||
|
if (!serverMode)
|
||||||
|
realignGuest = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t scancode = mapScancode(sc);
|
||||||
|
if (scancode == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (spice_key_down(scancode))
|
||||||
|
keyDown[sc] = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("SDL_KEYDOWN: failed to send message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SDL_KEYUP:
|
||||||
|
{
|
||||||
|
SDL_Scancode sc = event->key.keysym.scancode;
|
||||||
|
if (sc == SDL_SCANCODE_SCROLLLOCK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// avoid sending key up events when we didn't send a down
|
||||||
|
if (!keyDown[sc])
|
||||||
|
break;
|
||||||
|
|
||||||
|
uint32_t scancode = mapScancode(sc);
|
||||||
|
if (scancode == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (spice_key_up(scancode))
|
||||||
|
keyDown[sc] = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("SDL_KEYUP: failed to send message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SDL_MOUSEWHEEL:
|
||||||
|
if (
|
||||||
|
!spice_mouse_press (event->wheel.y == 1 ? 4 : 5) ||
|
||||||
|
!spice_mouse_release(event->wheel.y == 1 ? 4 : 5)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("SDL_MOUSEWHEEL: failed to send messages");
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
// The SPICE protocol doesn't support more than a standard PS/2 3 button mouse
|
||||||
|
if (event->button.button > 3)
|
||||||
|
break;
|
||||||
|
if (
|
||||||
|
!spice_mouse_position(event->button.x, event->button.y) ||
|
||||||
|
!spice_mouse_press(event->button.button)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
switch(event.window.event)
|
DEBUG_ERROR("SDL_MOUSEBUTTONDOWN: failed to send message");
|
||||||
{
|
|
||||||
case SDL_WINDOWEVENT_ENTER:
|
|
||||||
realignGuest = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
||||||
updatePositionInfo();
|
|
||||||
realignGuest = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (!params.useSpice)
|
case SDL_MOUSEBUTTONUP:
|
||||||
continue;
|
// The SPICE protocol doesn't support more than a standard PS/2 3 button mouse
|
||||||
|
if (event->button.button > 3)
|
||||||
switch(event.type)
|
break;
|
||||||
{
|
if (
|
||||||
case SDL_KEYDOWN:
|
!spice_mouse_position(event->button.x, event->button.y) ||
|
||||||
|
!spice_mouse_release(event->button.button)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
SDL_Scancode sc = event.key.keysym.scancode;
|
DEBUG_ERROR("SDL_MOUSEBUTTONUP: failed to send message");
|
||||||
if (sc == SDL_SCANCODE_SCROLLLOCK)
|
|
||||||
{
|
|
||||||
if (event.key.repeat)
|
|
||||||
break;
|
|
||||||
|
|
||||||
serverMode = !serverMode;
|
|
||||||
spice_mouse_mode(serverMode);
|
|
||||||
SDL_SetRelativeMouseMode(serverMode);
|
|
||||||
|
|
||||||
if (!serverMode)
|
|
||||||
realignGuest = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t scancode = mapScancode(sc);
|
|
||||||
if (scancode == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (spice_key_down(scancode))
|
|
||||||
keyDown[sc] = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("SDL_KEYDOWN: failed to send message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SDL_KEYUP:
|
default:
|
||||||
{
|
return 1;
|
||||||
SDL_Scancode sc = event.key.keysym.scancode;
|
|
||||||
if (sc == SDL_SCANCODE_SCROLLLOCK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// avoid sending key up events when we didn't send a down
|
|
||||||
if (!keyDown[sc])
|
|
||||||
break;
|
|
||||||
|
|
||||||
uint32_t scancode = mapScancode(sc);
|
|
||||||
if (scancode == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (spice_key_up(scancode))
|
|
||||||
keyDown[sc] = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("SDL_KEYUP: failed to send message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_MOUSEWHEEL:
|
|
||||||
if (
|
|
||||||
!spice_mouse_press (event.wheel.y == 1 ? 4 : 5) ||
|
|
||||||
!spice_mouse_release(event.wheel.y == 1 ? 4 : 5)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("SDL_MOUSEWHEEL: failed to send messages");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
!serverMode && (
|
|
||||||
event.motion.x < state.dstRect.x ||
|
|
||||||
event.motion.x > state.dstRect.x + state.dstRect.w ||
|
|
||||||
event.motion.y < state.dstRect.y ||
|
|
||||||
event.motion.y > state.dstRect.y + state.dstRect.h
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
realignGuest = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
if (realignGuest && state.haveCursorPos)
|
|
||||||
{
|
|
||||||
x = event.motion.x - state.dstRect.x;
|
|
||||||
y = event.motion.y - state.dstRect.y;
|
|
||||||
if (params.scaleMouseInput)
|
|
||||||
{
|
|
||||||
x = (float)x * state.scaleX;
|
|
||||||
y = (float)y * state.scaleY;
|
|
||||||
}
|
|
||||||
x -= state.cursor.x;
|
|
||||||
y -= state.cursor.y;
|
|
||||||
realignGuest = false;
|
|
||||||
|
|
||||||
if (!spice_mouse_motion(x, y))
|
|
||||||
DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = event.motion.xrel;
|
|
||||||
y = event.motion.yrel;
|
|
||||||
if (x != 0 || y != 0)
|
|
||||||
{
|
|
||||||
if (params.scaleMouseInput)
|
|
||||||
{
|
|
||||||
x = (float)x * state.scaleX;
|
|
||||||
y = (float)y * state.scaleY;
|
|
||||||
}
|
|
||||||
if (!spice_mouse_motion(x, y))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
// The SPICE protocol doesn't support more than a standard PS/2 3 button mouse
|
|
||||||
if (event.button.button > 3)
|
|
||||||
break;
|
|
||||||
if (
|
|
||||||
!spice_mouse_position(event.button.x, event.button.y) ||
|
|
||||||
!spice_mouse_press(event.button.button)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("SDL_MOUSEBUTTONDOWN: failed to send message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
// The SPICE protocol doesn't support more than a standard PS/2 3 button mouse
|
|
||||||
if (event.button.button > 3)
|
|
||||||
break;
|
|
||||||
if (
|
|
||||||
!spice_mouse_position(event.button.x, event.button.y) ||
|
|
||||||
!spice_mouse_release(event.button.button)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("SDL_MOUSEBUTTONUP: failed to send message");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -851,7 +839,7 @@ int run()
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Thread *t_spice = NULL;
|
SDL_Thread *t_spice = NULL;
|
||||||
SDL_Thread *t_event = NULL;
|
SDL_Thread *t_main = NULL;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
@ -885,12 +873,6 @@ int run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(t_event = SDL_CreateThread(eventThread, "eventThread", NULL)))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("event create thread failed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// flag the host that we are starting up this is important so that
|
// flag the host that we are starting up this is important so that
|
||||||
// the host wakes up if it is waiting on an interrupt, the host will
|
// the host wakes up if it is waiting on an interrupt, the host will
|
||||||
// also send us the current mouse shape since we won't know it yet
|
// also send us the current mouse shape since we won't know it yet
|
||||||
|
@ -914,26 +896,48 @@ int run()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(t_event = SDL_CreateThread(cursorThread, "cursorThread", NULL)))
|
|
||||||
|
if (!(t_main = SDL_CreateThread(cursorThread, "cursorThread", NULL)))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("cursor create thread failed");
|
DEBUG_ERROR("cursor create thread failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(t_event = SDL_CreateThread(frameThread, "frameThread", NULL)))
|
if (!(t_main = SDL_CreateThread(frameThread, "frameThread", NULL)))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("frame create thread failed");
|
DEBUG_ERROR("frame create thread failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mainThread();
|
if (!(t_main = SDL_CreateThread(renderThread, "renderThread", NULL)))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("render create thread failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure mouse acceleration is identical in server mode
|
||||||
|
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);
|
||||||
|
SDL_SetEventFilter(eventFilter, NULL);
|
||||||
|
|
||||||
|
while(state.running)
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while(SDL_PollEvent(&event))
|
||||||
|
if (event.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
if (!params.ignoreQuit)
|
||||||
|
state.running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.running = false;
|
state.running = false;
|
||||||
|
|
||||||
if (t_event)
|
if (t_main)
|
||||||
SDL_WaitThread(t_event, NULL);
|
SDL_WaitThread(t_main, NULL);
|
||||||
|
|
||||||
if (t_spice)
|
if (t_spice)
|
||||||
SDL_WaitThread(t_spice, NULL);
|
SDL_WaitThread(t_spice, NULL);
|
||||||
|
@ -1422,6 +1426,5 @@ int main(int argc, char * argv[])
|
||||||
free(opts->argv);
|
free(opts->argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
Loading…
Reference in a new issue