From 6878eee40a80404da4ffb827bb127ce4f95fa140 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 4 Jan 2021 12:04:43 +1100 Subject: [PATCH] [client] refactor cursor variables into their own global struct --- client/src/main.c | 210 +++++++++++++++++++++++----------------------- client/src/main.h | 103 ++++++++++++++--------- 2 files changed, 169 insertions(+), 144 deletions(-) diff --git a/client/src/main.c b/client/src/main.c index a6afb50f..01cb1b5c 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -72,6 +72,7 @@ static LGThread *t_frame = NULL; static SDL_Cursor *cursor = NULL; struct AppState state; +struct CursorState g_cursor; // this structure is initialized in config.c struct AppParams params = { 0 }; @@ -81,14 +82,14 @@ static void handleMouseMoveEvent(int ex, int ey); static void lgInit() { state.state = APP_STATE_RUNNING; - state.scale = false; - state.scaleX = 1.0f; - state.scaleY = 1.0f; state.resizeDone = true; - state.drawCursor = true; - state.haveCursorPos = false; - state.cursorInView = true; + g_cursor.scale = false; + 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() @@ -151,12 +152,12 @@ static void updatePositionInfo() } state.dstRect.valid = true; - state.scale = ( + g_cursor.scale = ( state.srcSize.y != state.dstRect.h || state.srcSize.x != state.dstRect.w); - state.scaleX = (float)state.srcSize.y / (float)state.dstRect.h; - state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w; + g_cursor.scaleX = (float)state.srcSize.y / (float)state.dstRect.h; + g_cursor.scaleY = (float)state.srcSize.x / (float)state.dstRect.w; } state.lgrResize = true; @@ -279,15 +280,15 @@ static int cursorThread(void * unused) { 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.lgrData, - state.cursorVisible && state.drawCursor, - state.cursor.x, - state.cursor.y + g_cursor.guest.visible && g_cursor.draw, + g_cursor.guest.x, + g_cursor.guest.y ); lgSignalEvent(e_frame); @@ -309,7 +310,7 @@ static int cursorThread(void * unused) KVMFRCursor * cursor = (KVMFRCursor *)msg.mem; - state.cursorVisible = + g_cursor.guest.visible = msg.udata & CURSOR_FLAG_VISIBLE; if (msg.udata & CURSOR_FLAG_SHAPE) @@ -325,8 +326,8 @@ static int cursorThread(void * unused) continue; } - state.cursor.hx = cursor->hx; - state.cursor.hy = cursor->hy; + g_cursor.guest.hx = cursor->hx; + g_cursor.guest.hy = cursor->hy; const uint8_t * data = (const uint8_t *)(cursor + 1); if (!state.lgr->on_mouse_shape( @@ -346,20 +347,20 @@ static int cursorThread(void * unused) if (msg.udata & CURSOR_FLAG_POSITION) { - state.cursor.x = cursor->x; - state.cursor.y = cursor->y; - state.haveCursorPos = true; + g_cursor.guest.x = cursor->x; + g_cursor.guest.y = cursor->y; + g_cursor.guest.valid = true; } lgmpClientMessageDone(queue); - state.updateCursor = false; + g_cursor.redraw = false; state.lgr->on_mouse_event ( state.lgrData, - state.cursorVisible && state.drawCursor, - state.cursor.x, - state.cursor.y + g_cursor.guest.visible && g_cursor.draw, + g_cursor.guest.x, + g_cursor.guest.y ); if (params.mouseRedraw) @@ -773,21 +774,21 @@ void spiceClipboardRequest(const SpiceDataType type) static void warpMouse(int x, int y) { - if (!state.cursorInWindow) + if (!g_cursor.inWindow) return; - if (state.warpState == WARP_STATE_WIN_EXIT) + if (g_cursor.warpState == WARP_STATE_WIN_EXIT) { SDL_WarpMouseInWindow(state.window, x, y); - state.warpState = WARP_STATE_OFF; + g_cursor.warpState = WARP_STATE_OFF; return; } - if (state.warpState == WARP_STATE_ON) + if (g_cursor.warpState == WARP_STATE_ON) { - state.warpToX = x; - state.warpToY = y; - state.warpState = WARP_STATE_ACTIVE; + g_cursor.warpTo.x = x; + g_cursor.warpTo.y = y; + g_cursor.warpState = WARP_STATE_ACTIVE; SDL_WarpMouseInWindow(state.window, x, y); } } @@ -809,33 +810,32 @@ static bool isValidCursorLocation(int x, int y) static void handleMouseMoveEvent(int ex, int ey) { SDL_Point delta = { - .x = ex - state.curLastX, - .y = ey - state.curLastY + .x = ex - g_cursor.last.x, + .y = ey - g_cursor.last.y }; if (delta.x == 0 && delta.y == 0) return; - state.curLastX = ex; - state.curLastY = ey; - state.haveCurLocal = true; + g_cursor.last.x = ex; + g_cursor.last.y = ey; - if (state.warpState == WARP_STATE_ACTIVE && - ex == state.warpToX && ey == state.warpToY) + if (g_cursor.warpState == WARP_STATE_ACTIVE && + ex == g_cursor.warpTo.x && ey == g_cursor.warpTo.y) { - state.warpState = WARP_STATE_ON; + g_cursor.warpState = WARP_STATE_ON; return; } - if (!state.cursorInWindow || state.ignoreInput || !params.useSpiceInput) + if (!g_cursor.inWindow || state.ignoreInput || !params.useSpiceInput) return; /* 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); if (ex < 50 || ex > state.windowW - 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); /* 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) { @@ -862,17 +862,17 @@ static void handleMouseMoveEvent(int ex, int ey) if (params.hideMouse) SDL_ShowCursor(SDL_DISABLE); - state.updateCursor = true; - state.drawCursor = true; + g_cursor.redraw = true; + g_cursor.draw = true; - if (state.warpState == WARP_STATE_OFF) - state.warpState = WARP_STATE_ON; + if (g_cursor.warpState == WARP_STATE_OFF) + g_cursor.warpState = WARP_STATE_ON; warpMouse(state.windowW / 2, state.windowH / 2); /* convert guest to local and calculate the delta */ - const int lx = ((state.cursor.x + state.cursor.hx) / state.scaleX) + state.dstRect.x; - const int ly = ((state.cursor.y + state.cursor.hy) / state.scaleY) + state.dstRect.y; + const int lx = ((g_cursor.guest.x + g_cursor.guest.hx) / g_cursor.scaleX) + state.dstRect.x; + const int ly = ((g_cursor.guest.y + g_cursor.guest.hy) / g_cursor.scaleY) + state.dstRect.y; delta.x = ex - lx; delta.y = ey - ly; } @@ -880,9 +880,9 @@ static void handleMouseMoveEvent(int ex, int ey) { /* cursor moved out */ SDL_ShowCursor(SDL_ENABLE); - state.updateCursor = true; + g_cursor.redraw = true; if (params.useSpiceInput && !params.alwaysShowCursor) - state.drawCursor = false; + g_cursor.draw = false; } } else if (inView) @@ -898,32 +898,32 @@ static void handleMouseMoveEvent(int ex, int ey) return; } - if (state.scale && params.scaleMouseInput && !state.grabMouse) + if (g_cursor.scale && params.scaleMouseInput && !g_cursor.grab) { - state.accX += (float)delta.x * state.scaleX; - state.accY += (float)delta.y * state.scaleY; - delta.x = floor(state.accX); - delta.y = floor(state.accY); - state.accX -= delta.x; - state.accY -= delta.y; + g_cursor.accX += (float)delta.x * g_cursor.scaleX; + g_cursor.accY += (float)delta.y * g_cursor.scaleY; + delta.x = floor(g_cursor.accX); + delta.y = floor(g_cursor.accY); + g_cursor.accX -= delta.x; + 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); - state.sensY += ((float)delta.y / 10.0f) * (state.mouseSens + 10); - delta.x = floor(state.sensX); - delta.y = floor(state.sensY); - state.sensX -= delta.x; - state.sensY -= delta.y; + g_cursor.sensX += ((float)delta.x / 10.0f) * (g_cursor.sens + 10); + g_cursor.sensY += ((float)delta.y / 10.0f) * (g_cursor.sens + 10); + delta.x = floor(g_cursor.sensX); + delta.y = floor(g_cursor.sensY); + g_cursor.sensX -= delta.x; + 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) / - state.scaleX; - const float fy = (float)(state.cursor.y + state.cursor.hy + delta.y) / - state.scaleY; + const float fx = (float)(g_cursor.guest.x + g_cursor.guest.hx + delta.x) / + g_cursor.scaleX; + const float fy = (float)(g_cursor.guest.y + g_cursor.guest.hy + delta.y) / + g_cursor.scaleY; const SDL_Point newPos = { .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)) { /* put the mouse where it should be and disable warp */ - state.warpState = WARP_STATE_WIN_EXIT; + g_cursor.warpState = WARP_STATE_WIN_EXIT; warpMouse( state.dstRect.x + newPos.x, state.dstRect.y + newPos.y @@ -977,33 +977,33 @@ static void handleResizeEvent(unsigned int w, unsigned int h) static void handleWindowLeave() { - state.cursorInWindow = false; + g_cursor.inWindow = false; if (!params.useSpiceInput) return; if (!params.alwaysShowCursor) - state.drawCursor = false; + g_cursor.draw = false; - state.cursorInView = false; - state.updateCursor = true; + g_cursor.inView = false; + g_cursor.redraw = true; } static void handleWindowEnter() { - state.cursorInWindow = true; + g_cursor.inWindow = true; - if (state.warpState == WARP_STATE_OFF) - state.warpState = WARP_STATE_ON; + if (g_cursor.warpState == WARP_STATE_OFF) + g_cursor.warpState = WARP_STATE_ON; if (!params.useSpiceInput) return; - if (!state.haveCursorPos) + if (!g_cursor.guest.valid) return; - state.drawCursor = true; - state.updateCursor = true; + g_cursor.draw = true; + g_cursor.redraw = true; } // only called for X11 @@ -1105,9 +1105,8 @@ int eventFilter(void * userdata, SDL_Event * event) if (xe.xcrossing.mode != NotifyNormal) break; - state.curLastX = xe.xcrossing.x; - state.curLastY = xe.xcrossing.y; - state.haveCurLocal = true; + g_cursor.last.x = xe.xcrossing.x; + g_cursor.last.y = xe.xcrossing.y; handleWindowEnter(); break; @@ -1115,9 +1114,8 @@ int eventFilter(void * userdata, SDL_Event * event) if (xe.xcrossing.mode != NotifyNormal) break; - state.curLastX = xe.xcrossing.x; - state.curLastY = xe.xcrossing.y; - state.haveCurLocal = true; + g_cursor.last.x = xe.xcrossing.x; + g_cursor.last.y = xe.xcrossing.y; handleWindowLeave(); break; @@ -1196,13 +1194,13 @@ int eventFilter(void * userdata, SDL_Event * event) { if (params.useSpiceInput) { - state.grabMouse = !state.grabMouse; + g_cursor.grab = !g_cursor.grab; if (state.wminfo.subsystem != SDL_SYSWM_X11) - SDL_SetWindowGrab(state.window, state.grabMouse); + SDL_SetWindowGrab(state.window, g_cursor.grab); app_alert( - state.grabMouse ? LG_ALERT_SUCCESS : LG_ALERT_WARNING, - state.grabMouse ? "Capture Enabled" : "Capture Disabled" + g_cursor.grab ? LG_ALERT_SUCCESS : LG_ALERT_WARNING, + g_cursor.grab ? "Capture Enabled" : "Capture Disabled" ); } } @@ -1239,7 +1237,7 @@ int eventFilter(void * userdata, SDL_Event * event) } case SDL_MOUSEWHEEL: - if (state.ignoreInput || !params.useSpiceInput || !state.cursorInView) + if (state.ignoreInput || !params.useSpiceInput || !g_cursor.inView) break; if ( @@ -1254,7 +1252,7 @@ int eventFilter(void * userdata, SDL_Event * event) case SDL_MOUSEBUTTONDOWN: { - if (state.ignoreInput || !params.useSpiceInput || !state.cursorInView) + if (state.ignoreInput || !params.useSpiceInput || !g_cursor.inView) break; int button = event->button.button; @@ -1271,7 +1269,7 @@ int eventFilter(void * userdata, SDL_Event * event) case SDL_MOUSEBUTTONUP: { - if (state.ignoreInput || !params.useSpiceInput || !state.cursorInView) + if (state.ignoreInput || !params.useSpiceInput || !g_cursor.inView) break; 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) { char * msg; - if (state.mouseSens < 9) - ++state.mouseSens; + if (g_cursor.sens < 9) + ++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( LG_ALERT_INFO, msg @@ -1388,10 +1386,10 @@ static void mouse_sens_dec(SDL_Scancode key, void * opaque) { char * msg; - if (state.mouseSens > -9) - --state.mouseSens; + if (g_cursor.sens > -9) + --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( LG_ALERT_INFO, msg @@ -1462,9 +1460,9 @@ static int lg_run() memset(&state, 0, sizeof(state)); lgInit(); - state.mouseSens = params.mouseSens; - if (state.mouseSens < -9) state.mouseSens = -9; - else if (state.mouseSens > 9) state.mouseSens = 9; + g_cursor.sens = params.mouseSens; + if (g_cursor.sens < -9) g_cursor.sens = -9; + else if (g_cursor.sens > 9) g_cursor.sens = 9; char* XDG_SESSION_TYPE = getenv("XDG_SESSION_TYPE"); @@ -1698,7 +1696,7 @@ static int lg_run() if (params.captureOnStart) { - state.grabMouse = true; + g_cursor.grab = true; if (state.wminfo.subsystem != SDL_SYSWM_X11) SDL_SetWindowGrab(state.window, true); } diff --git a/client/src/main.h b/client/src/main.h index 349895b5..ef67ee6b 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -36,20 +36,6 @@ enum RunState 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 { enum RunState state; @@ -66,26 +52,6 @@ struct AppState SDL_Rect border; SDL_Point srcSize; 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; void * lgrData; @@ -122,9 +88,6 @@ struct AppState KeybindHandle kbMouseSensInc; KeybindHandle kbMouseSensDec; KeybindHandle kbCtrlAltFn[12]; - - int mouseSens; - float sensX, sensY; }; struct AppParams @@ -169,8 +132,8 @@ struct AppParams unsigned int forceRendererIndex; const char * windowTitle; - int mouseSens; bool mouseRedraw; + int mouseSens; }; struct CBRequest @@ -187,6 +150,70 @@ struct KeybindHandle 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 extern struct AppState state; extern struct AppParams params;