[client] refactor cursor variables into their own global struct

This commit is contained in:
Geoffrey McRae 2021-01-04 12:04:43 +11:00
parent 9c941239ea
commit 6878eee40a
2 changed files with 169 additions and 144 deletions

View File

@ -72,6 +72,7 @@ static LGThread *t_frame = NULL;
static SDL_Cursor *cursor = NULL; static SDL_Cursor *cursor = NULL;
struct AppState state; struct AppState state;
struct CursorState g_cursor;
// this structure is initialized in config.c // this structure is initialized in config.c
struct AppParams params = { 0 }; struct AppParams params = { 0 };
@ -81,14 +82,14 @@ static void handleMouseMoveEvent(int ex, int ey);
static void lgInit() static void lgInit()
{ {
state.state = APP_STATE_RUNNING; state.state = APP_STATE_RUNNING;
state.scale = false;
state.scaleX = 1.0f;
state.scaleY = 1.0f;
state.resizeDone = true; state.resizeDone = true;
state.drawCursor = true;
state.haveCursorPos = false; g_cursor.scale = false;
state.cursorInView = true; g_cursor.scaleX = 1.0f;
g_cursor.scaleY = 1.0f;
g_cursor.draw = true;
g_cursor.inView = true;
g_cursor.guest.valid = false;
} }
static void updatePositionInfo() static void updatePositionInfo()
@ -151,12 +152,12 @@ static void updatePositionInfo()
} }
state.dstRect.valid = true; state.dstRect.valid = true;
state.scale = ( g_cursor.scale = (
state.srcSize.y != state.dstRect.h || state.srcSize.y != state.dstRect.h ||
state.srcSize.x != state.dstRect.w); state.srcSize.x != state.dstRect.w);
state.scaleX = (float)state.srcSize.y / (float)state.dstRect.h; g_cursor.scaleX = (float)state.srcSize.y / (float)state.dstRect.h;
state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w; g_cursor.scaleY = (float)state.srcSize.x / (float)state.dstRect.w;
} }
state.lgrResize = true; state.lgrResize = true;
@ -279,15 +280,15 @@ static int cursorThread(void * unused)
{ {
if (status == LGMP_ERR_QUEUE_EMPTY) if (status == LGMP_ERR_QUEUE_EMPTY)
{ {
if (state.updateCursor) if (g_cursor.redraw)
{ {
state.updateCursor = false; g_cursor.redraw = false;
state.lgr->on_mouse_event state.lgr->on_mouse_event
( (
state.lgrData, state.lgrData,
state.cursorVisible && state.drawCursor, g_cursor.guest.visible && g_cursor.draw,
state.cursor.x, g_cursor.guest.x,
state.cursor.y g_cursor.guest.y
); );
lgSignalEvent(e_frame); lgSignalEvent(e_frame);
@ -309,7 +310,7 @@ static int cursorThread(void * unused)
KVMFRCursor * cursor = (KVMFRCursor *)msg.mem; KVMFRCursor * cursor = (KVMFRCursor *)msg.mem;
state.cursorVisible = g_cursor.guest.visible =
msg.udata & CURSOR_FLAG_VISIBLE; msg.udata & CURSOR_FLAG_VISIBLE;
if (msg.udata & CURSOR_FLAG_SHAPE) if (msg.udata & CURSOR_FLAG_SHAPE)
@ -325,8 +326,8 @@ static int cursorThread(void * unused)
continue; continue;
} }
state.cursor.hx = cursor->hx; g_cursor.guest.hx = cursor->hx;
state.cursor.hy = cursor->hy; g_cursor.guest.hy = cursor->hy;
const uint8_t * data = (const uint8_t *)(cursor + 1); const uint8_t * data = (const uint8_t *)(cursor + 1);
if (!state.lgr->on_mouse_shape( if (!state.lgr->on_mouse_shape(
@ -346,20 +347,20 @@ static int cursorThread(void * unused)
if (msg.udata & CURSOR_FLAG_POSITION) if (msg.udata & CURSOR_FLAG_POSITION)
{ {
state.cursor.x = cursor->x; g_cursor.guest.x = cursor->x;
state.cursor.y = cursor->y; g_cursor.guest.y = cursor->y;
state.haveCursorPos = true; g_cursor.guest.valid = true;
} }
lgmpClientMessageDone(queue); lgmpClientMessageDone(queue);
state.updateCursor = false; g_cursor.redraw = false;
state.lgr->on_mouse_event state.lgr->on_mouse_event
( (
state.lgrData, state.lgrData,
state.cursorVisible && state.drawCursor, g_cursor.guest.visible && g_cursor.draw,
state.cursor.x, g_cursor.guest.x,
state.cursor.y g_cursor.guest.y
); );
if (params.mouseRedraw) if (params.mouseRedraw)
@ -773,21 +774,21 @@ void spiceClipboardRequest(const SpiceDataType type)
static void warpMouse(int x, int y) static void warpMouse(int x, int y)
{ {
if (!state.cursorInWindow) if (!g_cursor.inWindow)
return; return;
if (state.warpState == WARP_STATE_WIN_EXIT) if (g_cursor.warpState == WARP_STATE_WIN_EXIT)
{ {
SDL_WarpMouseInWindow(state.window, x, y); SDL_WarpMouseInWindow(state.window, x, y);
state.warpState = WARP_STATE_OFF; g_cursor.warpState = WARP_STATE_OFF;
return; return;
} }
if (state.warpState == WARP_STATE_ON) if (g_cursor.warpState == WARP_STATE_ON)
{ {
state.warpToX = x; g_cursor.warpTo.x = x;
state.warpToY = y; g_cursor.warpTo.y = y;
state.warpState = WARP_STATE_ACTIVE; g_cursor.warpState = WARP_STATE_ACTIVE;
SDL_WarpMouseInWindow(state.window, x, y); SDL_WarpMouseInWindow(state.window, x, y);
} }
} }
@ -809,33 +810,32 @@ static bool isValidCursorLocation(int x, int y)
static void handleMouseMoveEvent(int ex, int ey) static void handleMouseMoveEvent(int ex, int ey)
{ {
SDL_Point delta = { SDL_Point delta = {
.x = ex - state.curLastX, .x = ex - g_cursor.last.x,
.y = ey - state.curLastY .y = ey - g_cursor.last.y
}; };
if (delta.x == 0 && delta.y == 0) if (delta.x == 0 && delta.y == 0)
return; return;
state.curLastX = ex; g_cursor.last.x = ex;
state.curLastY = ey; g_cursor.last.y = ey;
state.haveCurLocal = true;
if (state.warpState == WARP_STATE_ACTIVE && if (g_cursor.warpState == WARP_STATE_ACTIVE &&
ex == state.warpToX && ey == state.warpToY) ex == g_cursor.warpTo.x && ey == g_cursor.warpTo.y)
{ {
state.warpState = WARP_STATE_ON; g_cursor.warpState = WARP_STATE_ON;
return; return;
} }
if (!state.cursorInWindow || state.ignoreInput || !params.useSpiceInput) if (!g_cursor.inWindow || state.ignoreInput || !params.useSpiceInput)
return; return;
/* if we don't have the current cursor pos just send cursor movements */ /* if we don't have the current cursor pos just send cursor movements */
if (!state.haveCursorPos) if (!g_cursor.guest.valid)
{ {
if (state.grabMouse) if (g_cursor.grab)
{ {
state.cursorInView = true; g_cursor.inView = true;
spice_mouse_motion(delta.x, delta.y); spice_mouse_motion(delta.x, delta.y);
if (ex < 50 || ex > state.windowW - 50 || if (ex < 50 || ex > state.windowW - 50 ||
ey < 50 || ey > state.windowH - 50) ey < 50 || ey > state.windowH - 50)
@ -852,9 +852,9 @@ static void handleMouseMoveEvent(int ex, int ey)
ey >= state.dstRect.y + state.dstRect.h); ey >= state.dstRect.y + state.dstRect.h);
/* if the cursor is to move in/outside the display area */ /* if the cursor is to move in/outside the display area */
if (state.cursorInView != inView) if (g_cursor.inView != inView)
{ {
state.cursorInView = inView; g_cursor.inView = inView;
if (inView) if (inView)
{ {
@ -862,17 +862,17 @@ static void handleMouseMoveEvent(int ex, int ey)
if (params.hideMouse) if (params.hideMouse)
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
state.updateCursor = true; g_cursor.redraw = true;
state.drawCursor = true; g_cursor.draw = true;
if (state.warpState == WARP_STATE_OFF) if (g_cursor.warpState == WARP_STATE_OFF)
state.warpState = WARP_STATE_ON; g_cursor.warpState = WARP_STATE_ON;
warpMouse(state.windowW / 2, state.windowH / 2); warpMouse(state.windowW / 2, state.windowH / 2);
/* convert guest to local and calculate the delta */ /* convert guest to local and calculate the delta */
const int lx = ((state.cursor.x + state.cursor.hx) / state.scaleX) + state.dstRect.x; const int lx = ((g_cursor.guest.x + g_cursor.guest.hx) / g_cursor.scaleX) + state.dstRect.x;
const int ly = ((state.cursor.y + state.cursor.hy) / state.scaleY) + state.dstRect.y; const int ly = ((g_cursor.guest.y + g_cursor.guest.hy) / g_cursor.scaleY) + state.dstRect.y;
delta.x = ex - lx; delta.x = ex - lx;
delta.y = ey - ly; delta.y = ey - ly;
} }
@ -880,9 +880,9 @@ static void handleMouseMoveEvent(int ex, int ey)
{ {
/* cursor moved out */ /* cursor moved out */
SDL_ShowCursor(SDL_ENABLE); SDL_ShowCursor(SDL_ENABLE);
state.updateCursor = true; g_cursor.redraw = true;
if (params.useSpiceInput && !params.alwaysShowCursor) if (params.useSpiceInput && !params.alwaysShowCursor)
state.drawCursor = false; g_cursor.draw = false;
} }
} }
else if (inView) else if (inView)
@ -898,32 +898,32 @@ static void handleMouseMoveEvent(int ex, int ey)
return; return;
} }
if (state.scale && params.scaleMouseInput && !state.grabMouse) if (g_cursor.scale && params.scaleMouseInput && !g_cursor.grab)
{ {
state.accX += (float)delta.x * state.scaleX; g_cursor.accX += (float)delta.x * g_cursor.scaleX;
state.accY += (float)delta.y * state.scaleY; g_cursor.accY += (float)delta.y * g_cursor.scaleY;
delta.x = floor(state.accX); delta.x = floor(g_cursor.accX);
delta.y = floor(state.accY); delta.y = floor(g_cursor.accY);
state.accX -= delta.x; g_cursor.accX -= delta.x;
state.accY -= delta.y; g_cursor.accY -= delta.y;
} }
if (state.grabMouse && state.mouseSens != 0) if (g_cursor.grab && g_cursor.sens != 0)
{ {
state.sensX += ((float)delta.x / 10.0f) * (state.mouseSens + 10); g_cursor.sensX += ((float)delta.x / 10.0f) * (g_cursor.sens + 10);
state.sensY += ((float)delta.y / 10.0f) * (state.mouseSens + 10); g_cursor.sensY += ((float)delta.y / 10.0f) * (g_cursor.sens + 10);
delta.x = floor(state.sensX); delta.x = floor(g_cursor.sensX);
delta.y = floor(state.sensY); delta.y = floor(g_cursor.sensY);
state.sensX -= delta.x; g_cursor.sensX -= delta.x;
state.sensY -= delta.y; g_cursor.sensY -= delta.y;
} }
if (!state.grabMouse && state.warpState == WARP_STATE_ON) if (!g_cursor.grab && g_cursor.warpState == WARP_STATE_ON)
{ {
const float fx = (float)(state.cursor.x + state.cursor.hx + delta.x) / const float fx = (float)(g_cursor.guest.x + g_cursor.guest.hx + delta.x) /
state.scaleX; g_cursor.scaleX;
const float fy = (float)(state.cursor.y + state.cursor.hy + delta.y) / const float fy = (float)(g_cursor.guest.y + g_cursor.guest.hy + delta.y) /
state.scaleY; g_cursor.scaleY;
const SDL_Point newPos = const SDL_Point newPos =
{ {
.x = fx < 0.0f ? floor(fx) : (fx >= state.dstRect.w ? ceil(fx) : round(fx)), .x = fx < 0.0f ? floor(fx) : (fx >= state.dstRect.w ? ceil(fx) : round(fx)),
@ -942,7 +942,7 @@ static void handleMouseMoveEvent(int ex, int ey)
if (isValidCursorLocation(nx, ny)) if (isValidCursorLocation(nx, ny))
{ {
/* put the mouse where it should be and disable warp */ /* put the mouse where it should be and disable warp */
state.warpState = WARP_STATE_WIN_EXIT; g_cursor.warpState = WARP_STATE_WIN_EXIT;
warpMouse( warpMouse(
state.dstRect.x + newPos.x, state.dstRect.x + newPos.x,
state.dstRect.y + newPos.y state.dstRect.y + newPos.y
@ -977,33 +977,33 @@ static void handleResizeEvent(unsigned int w, unsigned int h)
static void handleWindowLeave() static void handleWindowLeave()
{ {
state.cursorInWindow = false; g_cursor.inWindow = false;
if (!params.useSpiceInput) if (!params.useSpiceInput)
return; return;
if (!params.alwaysShowCursor) if (!params.alwaysShowCursor)
state.drawCursor = false; g_cursor.draw = false;
state.cursorInView = false; g_cursor.inView = false;
state.updateCursor = true; g_cursor.redraw = true;
} }
static void handleWindowEnter() static void handleWindowEnter()
{ {
state.cursorInWindow = true; g_cursor.inWindow = true;
if (state.warpState == WARP_STATE_OFF) if (g_cursor.warpState == WARP_STATE_OFF)
state.warpState = WARP_STATE_ON; g_cursor.warpState = WARP_STATE_ON;
if (!params.useSpiceInput) if (!params.useSpiceInput)
return; return;
if (!state.haveCursorPos) if (!g_cursor.guest.valid)
return; return;
state.drawCursor = true; g_cursor.draw = true;
state.updateCursor = true; g_cursor.redraw = true;
} }
// only called for X11 // only called for X11
@ -1105,9 +1105,8 @@ int eventFilter(void * userdata, SDL_Event * event)
if (xe.xcrossing.mode != NotifyNormal) if (xe.xcrossing.mode != NotifyNormal)
break; break;
state.curLastX = xe.xcrossing.x; g_cursor.last.x = xe.xcrossing.x;
state.curLastY = xe.xcrossing.y; g_cursor.last.y = xe.xcrossing.y;
state.haveCurLocal = true;
handleWindowEnter(); handleWindowEnter();
break; break;
@ -1115,9 +1114,8 @@ int eventFilter(void * userdata, SDL_Event * event)
if (xe.xcrossing.mode != NotifyNormal) if (xe.xcrossing.mode != NotifyNormal)
break; break;
state.curLastX = xe.xcrossing.x; g_cursor.last.x = xe.xcrossing.x;
state.curLastY = xe.xcrossing.y; g_cursor.last.y = xe.xcrossing.y;
state.haveCurLocal = true;
handleWindowLeave(); handleWindowLeave();
break; break;
@ -1196,13 +1194,13 @@ int eventFilter(void * userdata, SDL_Event * event)
{ {
if (params.useSpiceInput) if (params.useSpiceInput)
{ {
state.grabMouse = !state.grabMouse; g_cursor.grab = !g_cursor.grab;
if (state.wminfo.subsystem != SDL_SYSWM_X11) if (state.wminfo.subsystem != SDL_SYSWM_X11)
SDL_SetWindowGrab(state.window, state.grabMouse); SDL_SetWindowGrab(state.window, g_cursor.grab);
app_alert( app_alert(
state.grabMouse ? LG_ALERT_SUCCESS : LG_ALERT_WARNING, g_cursor.grab ? LG_ALERT_SUCCESS : LG_ALERT_WARNING,
state.grabMouse ? "Capture Enabled" : "Capture Disabled" g_cursor.grab ? "Capture Enabled" : "Capture Disabled"
); );
} }
} }
@ -1239,7 +1237,7 @@ int eventFilter(void * userdata, SDL_Event * event)
} }
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
if (state.ignoreInput || !params.useSpiceInput || !state.cursorInView) if (state.ignoreInput || !params.useSpiceInput || !g_cursor.inView)
break; break;
if ( if (
@ -1254,7 +1252,7 @@ int eventFilter(void * userdata, SDL_Event * event)
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
{ {
if (state.ignoreInput || !params.useSpiceInput || !state.cursorInView) if (state.ignoreInput || !params.useSpiceInput || !g_cursor.inView)
break; break;
int button = event->button.button; int button = event->button.button;
@ -1271,7 +1269,7 @@ int eventFilter(void * userdata, SDL_Event * event)
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
{ {
if (state.ignoreInput || !params.useSpiceInput || !state.cursorInView) if (state.ignoreInput || !params.useSpiceInput || !g_cursor.inView)
break; break;
int button = event->button.button; int button = event->button.button;
@ -1373,10 +1371,10 @@ static void quit(SDL_Scancode key, void * opaque)
static void mouse_sens_inc(SDL_Scancode key, void * opaque) static void mouse_sens_inc(SDL_Scancode key, void * opaque)
{ {
char * msg; char * msg;
if (state.mouseSens < 9) if (g_cursor.sens < 9)
++state.mouseSens; ++g_cursor.sens;
alloc_sprintf(&msg, "Sensitivity: %s%d", state.mouseSens > 0 ? "+" : "", state.mouseSens); alloc_sprintf(&msg, "Sensitivity: %s%d", g_cursor.sens > 0 ? "+" : "", g_cursor.sens);
app_alert( app_alert(
LG_ALERT_INFO, LG_ALERT_INFO,
msg msg
@ -1388,10 +1386,10 @@ static void mouse_sens_dec(SDL_Scancode key, void * opaque)
{ {
char * msg; char * msg;
if (state.mouseSens > -9) if (g_cursor.sens > -9)
--state.mouseSens; --g_cursor.sens;
alloc_sprintf(&msg, "Sensitivity: %s%d", state.mouseSens > 0 ? "+" : "", state.mouseSens); alloc_sprintf(&msg, "Sensitivity: %s%d", g_cursor.sens > 0 ? "+" : "", g_cursor.sens);
app_alert( app_alert(
LG_ALERT_INFO, LG_ALERT_INFO,
msg msg
@ -1462,9 +1460,9 @@ static int lg_run()
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
lgInit(); lgInit();
state.mouseSens = params.mouseSens; g_cursor.sens = params.mouseSens;
if (state.mouseSens < -9) state.mouseSens = -9; if (g_cursor.sens < -9) g_cursor.sens = -9;
else if (state.mouseSens > 9) state.mouseSens = 9; else if (g_cursor.sens > 9) g_cursor.sens = 9;
char* XDG_SESSION_TYPE = getenv("XDG_SESSION_TYPE"); char* XDG_SESSION_TYPE = getenv("XDG_SESSION_TYPE");
@ -1698,7 +1696,7 @@ static int lg_run()
if (params.captureOnStart) if (params.captureOnStart)
{ {
state.grabMouse = true; g_cursor.grab = true;
if (state.wminfo.subsystem != SDL_SYSWM_X11) if (state.wminfo.subsystem != SDL_SYSWM_X11)
SDL_SetWindowGrab(state.window, true); SDL_SetWindowGrab(state.window, true);
} }

View File

@ -36,20 +36,6 @@ enum RunState
APP_STATE_SHUTDOWN APP_STATE_SHUTDOWN
}; };
struct CursorInfo
{
int x , y;
int hx, hy;
};
enum WarpState
{
WARP_STATE_ON,
WARP_STATE_ACTIVE,
WARP_STATE_WIN_EXIT,
WARP_STATE_OFF
};
struct AppState struct AppState
{ {
enum RunState state; enum RunState state;
@ -66,26 +52,6 @@ struct AppState
SDL_Rect border; SDL_Rect border;
SDL_Point srcSize; SDL_Point srcSize;
LG_RendererRect dstRect; LG_RendererRect dstRect;
struct CursorInfo cursor;
bool cursorVisible;
bool cursorInWindow;
bool grabMouse;
bool haveCursorPos;
bool drawCursor;
bool cursorInView;
bool updateCursor;
bool initialCursorSync;
bool scale;
float scaleX, scaleY;
float accX, accY;
int curLastX;
int curLastY;
bool haveCurLocal;
bool haveAligned;
enum WarpState warpState;
int warpToX , warpToY;
const LG_Renderer * lgr; const LG_Renderer * lgr;
void * lgrData; void * lgrData;
@ -122,9 +88,6 @@ struct AppState
KeybindHandle kbMouseSensInc; KeybindHandle kbMouseSensInc;
KeybindHandle kbMouseSensDec; KeybindHandle kbMouseSensDec;
KeybindHandle kbCtrlAltFn[12]; KeybindHandle kbCtrlAltFn[12];
int mouseSens;
float sensX, sensY;
}; };
struct AppParams struct AppParams
@ -169,8 +132,8 @@ struct AppParams
unsigned int forceRendererIndex; unsigned int forceRendererIndex;
const char * windowTitle; const char * windowTitle;
int mouseSens;
bool mouseRedraw; bool mouseRedraw;
int mouseSens;
}; };
struct CBRequest struct CBRequest
@ -187,6 +150,70 @@ struct KeybindHandle
void * opaque; void * opaque;
}; };
enum WarpState
{
WARP_STATE_ON,
WARP_STATE_ACTIVE,
WARP_STATE_WIN_EXIT,
WARP_STATE_OFF
};
struct CursorInfo
{
/* x & y postiion */
int x , y;
/* pointer hotspot offsets */
int hx, hy;
/* true if the pointer is visible on the guest */
bool visible;
/* true if the details in this struct are valid */
bool valid;
};
struct CursorState
{
/* cursor is in grab mode */
bool grab;
/* true if we are to draw the cursor on screen */
bool draw;
/* true if the cursor is currently in our window */
bool inWindow;
/* true if the cursor is currently in the guest view area */
bool inView;
/* true if the cursor needs re-drawing/updating */
bool redraw;
/* true if the cursor movements should be scaled */
bool scale;
/* the amount to scale the X & Y movements by */
float scaleX, scaleY;
/* the error accumulators */
float accX, accY;
/* the last local X & Y positions */
SDL_Point last;
/* the scale factors for the mouse sensitiviy */
int sens;
float sensX, sensY;
/* the mouse warp state and target */
enum WarpState warpState;
SDL_Point warpTo;
/* the guest's cursor position */
struct CursorInfo guest;
};
// forwards // forwards
extern struct AppState state; extern struct AppState state;
extern struct AppParams params; extern struct AppParams params;