Mouse wheel and absolute movement support in rawinput mouse

note: absolute movement support is experimental, but it seems to work fine over RDP. Should solve #308
This commit is contained in:
driver1998
2019-03-20 13:59:25 +08:00
parent 7ccd79e109
commit 18a55b85df

View File

@@ -33,6 +33,7 @@ typedef struct {
int buttons; int buttons;
int dx; int dx;
int dy; int dy;
int dwheel;
} MOUSESTATE; } MOUSESTATE;
MOUSESTATE mousestate; MOUSESTATE mousestate;
@@ -62,6 +63,7 @@ win_mouse_handle(LPARAM lParam, int infocus)
uint32_t ri_size = 0; uint32_t ri_size = 0;
UINT size; UINT size;
RAWINPUT *raw; RAWINPUT *raw;
RAWMOUSE state;
if (! infocus) return; if (! infocus) return;
@@ -74,35 +76,51 @@ win_mouse_handle(LPARAM lParam, int infocus)
/* Here we read the raw input data for the mouse */ /* Here we read the raw input data for the mouse */
ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT,
raw, &size, sizeof(RAWINPUTHEADER)); raw, &size, sizeof(RAWINPUTHEADER));
if (ri_size != size) return; if (ri_size != size) goto err;
/* If the input is mouse, we process it */ /* If the input is not a mouse, we ignore it */
if (raw->header.dwType == RIM_TYPEMOUSE) { if (raw->header.dwType != RIM_TYPEMOUSE) goto err;
RAWMOUSE state = raw->data.mouse;
if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) state = raw->data.mouse;
mousestate.buttons |= 1;
else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
mousestate.buttons &= ~1;
if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) /* read mouse buttons and wheel */
mousestate.buttons |= 4; if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN)
else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) mousestate.buttons |= 1;
mousestate.buttons &= ~4; else if (state.usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP)
mousestate.buttons &= ~1;
if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)
mousestate.buttons |= 2; mousestate.buttons |= 4;
else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) else if (state.usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP)
mousestate.buttons &= ~2; mousestate.buttons &= ~4;
static int x = 0, y = 0; if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN)
if (x != state.lLastX || y != state.lLastY) { mousestate.buttons |= 2;
mousestate.dx += state.lLastX; else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP)
mousestate.dy += state.lLastY; mousestate.buttons &= ~2;
x = state.lLastX;
y = state.lLastY; if (state.usButtonFlags & RI_MOUSE_WHEEL) {
} mousestate.dwheel += (SHORT)state.usButtonData / 120;
} }
if (state.usFlags & MOUSE_MOVE_RELATIVE) {
/* relative mouse, i.e. regular mouse */
mousestate.dx += state.lLastX;
mousestate.dy += state.lLastY;
} else if (state.usFlags & MOUSE_MOVE_ABSOLUTE) {
/* absolute mouse, i.e. RDP or VNC
* seems to work fine for RDP on Windows 10
* Not sure about other environments.
*/
static int x=state.lLastX, y=state.lLastY;
mousestate.dx += (state.lLastX - x)/100;
mousestate.dy += (state.lLastY - y)/100;
x=state.lLastX;
y=state.lLastY;
}
err:
free(raw); free(raw);
} }
@@ -122,13 +140,16 @@ mouse_poll(void)
{ {
static int b = 0; static int b = 0;
if (mouse_capture || video_fullscreen) { if (mouse_capture || video_fullscreen) {
if (mousestate.dx != 0 || mousestate.dy != 0) { if (mousestate.dx != 0 || mousestate.dy != 0 || mousestate.dwheel != 0) {
mouse_x += mousestate.dx; mouse_x += mousestate.dx;
mouse_y += mousestate.dy; mouse_y += mousestate.dy;
mouse_z = 0; mouse_z = mousestate.dwheel;
mousestate.dx=0; mousestate.dx=0;
mousestate.dy=0; mousestate.dy=0;
mousestate.dwheel=0;
//pclog("dx=%d, dy=%d, dwheel=%d\n", mouse_x, mouse_y, mouse_z);
} }
if (b != mousestate.buttons) { if (b != mousestate.buttons) {