[client] add mouse input scaling feature for stretched/scaled windows

This commit is contained in:
Geoffrey McRae 2017-12-01 12:45:23 +11:00
parent 2c7e7a0a0b
commit 9831de92e1

View File

@ -47,6 +47,10 @@ struct AppState
bool started; bool started;
bool windowChanged; bool windowChanged;
int offsetX, offsetY;
int guestW, guestH;
float scaleX, scaleY;
SDL_Window * window; SDL_Window * window;
SDL_Renderer * renderer; SDL_Renderer * renderer;
struct KVMGFXHeader * shm; struct KVMGFXHeader * shm;
@ -68,6 +72,7 @@ struct AppParams
bool useSpice; bool useSpice;
const char * spiceHost; const char * spiceHost;
unsigned int spicePort; unsigned int spicePort;
bool scaleMouseInput;
}; };
struct AppState state; struct AppState state;
@ -87,7 +92,8 @@ struct AppParams params =
.useMipmap = true, .useMipmap = true,
.useSpice = true, .useSpice = true,
.spiceHost = "127.0.0.1", .spiceHost = "127.0.0.1",
.spicePort = 5900 .spicePort = 5900,
.scaleMouseInput = true
}; };
inline bool areFormatsSame(const struct KVMGFXHeader s1, const struct KVMGFXHeader s2) inline bool areFormatsSame(const struct KVMGFXHeader s1, const struct KVMGFXHeader s2)
@ -308,6 +314,13 @@ int renderThread(void * unused)
} }
} }
state.offsetX = dest.x;
state.offsetY = dest.y;
state.guestW = dest.w;
state.guestH = dest.h;
state.scaleX = (float)header.height / dest.h;
state.scaleY = (float)header.width / dest.w;
SDL_RenderClear(state.renderer); SDL_RenderClear(state.renderer);
if (state.hasBufferStorage) if (state.hasBufferStorage)
{ {
@ -560,27 +573,54 @@ int eventThread(void * arg)
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
{ {
if (
event.motion.x < state.offsetX ||
event.motion.x > state.offsetX + state.guestW ||
event.motion.y < state.offsetY ||
event.motion.y > state.offsetY + state.guestH
)
{
realignGuest = true;
break;
}
int x = 0; int x = 0;
int y = 0; int y = 0;
if (realignGuest || state.windowChanged) if (realignGuest || state.windowChanged)
{ {
x = event.motion.x - state.shm->mouseX; x = event.motion.x - state.offsetX;
y = event.motion.y - state.shm->mouseY; y = event.motion.y - state.offsetY;
if (params.scaleMouseInput)
{
x *= state.scaleX;
y *= state.scaleY;
}
x -= state.shm->mouseX;
y -= state.shm->mouseY;
realignGuest = false; realignGuest = false;
state.windowChanged = false; state.windowChanged = false;
}
else if (!spice_mouse_motion(x, y))
{ DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message");
x = event.motion.xrel;
y = event.motion.yrel; break;
} }
x = event.motion.xrel;
y = event.motion.yrel;
if (x != 0 || y != 0) if (x != 0 || y != 0)
{
if (params.scaleMouseInput)
{
x *= state.scaleX;
y *= state.scaleY;
}
if (!spice_mouse_motion(x, y)) if (!spice_mouse_motion(x, y))
{ {
DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message"); DEBUG_ERROR("SDL_MOUSEMOTION: failed to send message");
break; break;
} }
}
break; break;
} }
@ -629,6 +669,8 @@ int run()
{ {
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
state.running = true; state.running = true;
state.scaleX = 1.0f;
state.scaleY = 1.0f;
if (SDL_Init(SDL_INIT_VIDEO) < 0) if (SDL_Init(SDL_INIT_VIDEO) < 0)
{ {
@ -791,6 +833,7 @@ void doHelp(char * app)
" -s Disable spice client\n" " -s Disable spice client\n"
" -c HOST Specify the spice host [current: %s]\n" " -c HOST Specify the spice host [current: %s]\n"
" -p PORT Specify the spice port [current: %d]\n" " -p PORT Specify the spice port [current: %d]\n"
" -j Disable cursor position scaling\n"
"\n" "\n"
" -g Disable OpenGL 4.3 Buffer Storage (GL_ARB_buffer_storage)\n" " -g Disable OpenGL 4.3 Buffer Storage (GL_ARB_buffer_storage)\n"
" -m Disable mipmapping\n" " -m Disable mipmapping\n"
@ -869,6 +912,10 @@ int main(int argc, char * argv[])
params.spicePort = atoi(optarg); params.spicePort = atoi(optarg);
break; break;
case 'j':
params.scaleMouseInput = false;
break;
case 'g': case 'g':
params.useBufferStorage = false; params.useBufferStorage = false;
break; break;