Skip to content

(#126) Add rounding to fix mouse drift #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 76 additions & 79 deletions src/win32/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <math.h> /* For floor() */

#if !defined(M_SQRT2)
#define M_SQRT2 1.4142135623730950488016887 /* Fix for MSVC. */
#define M_SQRT2 1.4142135623730950488016887 /* Fix for MSVC. */
#endif

/**
Expand All @@ -15,121 +15,118 @@
* irrespective of resolution
* https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput#remarks
*/
#define ABSOLUTE_COORD_CONST 65536
#define ABSOLUTE_COORD_CONST 65536

#define MMMouseToMEventF(down, button) \
(down ? MMMouseDownToMEventF(button) : MMMouseUpToMEventF(button))
(down ? MMMouseDownToMEventF(button) : MMMouseUpToMEventF(button))

#define MMMouseUpToMEventF(button) \
((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTUP \
: ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTUP \
: MOUSEEVENTF_MIDDLEUP))
((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTUP \
: ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTUP \
: MOUSEEVENTF_MIDDLEUP))

#define MMMouseDownToMEventF(button) \
((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTDOWN \
: ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTDOWN \
: MOUSEEVENTF_MIDDLEDOWN))
((button) == LEFT_BUTTON ? MOUSEEVENTF_LEFTDOWN \
: ((button) == RIGHT_BUTTON ? MOUSEEVENTF_RIGHTDOWN \
: MOUSEEVENTF_MIDDLEDOWN))

static int32_t DEFAULT_DOUBLE_CLICK_INTERVAL_MS = 200;

MMPoint CalculateAbsoluteCoordinates(MMPoint point) {
MMSize displaySize = getMainDisplaySize();
return MMPointMake(((float) point.x / displaySize.width) * ABSOLUTE_COORD_CONST, ((float) point.y / displaySize.height) * ABSOLUTE_COORD_CONST);
MMSize displaySize = getMainDisplaySize();
return MMPointMake(
ceil(point.x * ABSOLUTE_COORD_CONST / displaySize.width),
ceil(point.y * ABSOLUTE_COORD_CONST / displaySize.height)
);
}

/**
* Move the mouse to a specific point.
* @param point The coordinates to move the mouse to (x, y).
*/
void moveMouse(MMPoint point) {
INPUT mouseInput;
MMPoint pointAbsolute = CalculateAbsoluteCoordinates(point);
mouseInput.type = INPUT_MOUSE;
mouseInput.mi.dx = pointAbsolute.x;
mouseInput.mi.dy = pointAbsolute.y;
mouseInput.mi.mouseData = 0;
mouseInput.mi.time = 0;
mouseInput.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
mouseInput.mi.dwExtraInfo = 0;
SendInput(1, & mouseInput, sizeof(mouseInput));
INPUT mouseInput;
MMPoint pointAbsolute = CalculateAbsoluteCoordinates(point);
mouseInput.type = INPUT_MOUSE;
mouseInput.mi.dx = pointAbsolute.x;
mouseInput.mi.dy = pointAbsolute.y;
mouseInput.mi.mouseData = 0;
mouseInput.mi.time = 0;
mouseInput.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
mouseInput.mi.dwExtraInfo = 0;
SendInput(1, &mouseInput, sizeof(mouseInput));
}

void dragMouse(MMPoint point, const MMMouseButton button)
{
(void)button;
moveMouse(point);
void dragMouse(MMPoint point, const MMMouseButton button) {
(void) button;
moveMouse(point);
}

MMPoint getMousePos()
{
POINT point;
GetCursorPos(&point);
MMPoint getMousePos() {
POINT point;
GetCursorPos(&point);

return MMPointFromPOINT(point);
return MMPointFromPOINT(point);
}

/**
* Press down a button, or release it.
* @param down True for down, false for up.
* @param button The button to press down or release.
*/
void toggleMouse(bool down, MMMouseButton button)
{
INPUT mouseInput;
mouseInput.type = INPUT_MOUSE;
mouseInput.mi.mouseData = 0;
mouseInput.mi.dx = 0;
mouseInput.mi.dy = 0;
mouseInput.mi.time = 0;
mouseInput.mi.dwFlags = MMMouseToMEventF(down, button);
SendInput(1, &mouseInput, sizeof(mouseInput));
void toggleMouse(bool down, MMMouseButton button) {
INPUT mouseInput;
mouseInput.type = INPUT_MOUSE;
mouseInput.mi.mouseData = 0;
mouseInput.mi.dx = 0;
mouseInput.mi.dy = 0;
mouseInput.mi.time = 0;
mouseInput.mi.dwFlags = MMMouseToMEventF(down, button);
SendInput(1, &mouseInput, sizeof(mouseInput));
}

void clickMouse(MMMouseButton button)
{
toggleMouse(true, button);
toggleMouse(false, button);
void clickMouse(MMMouseButton button) {
toggleMouse(true, button);
toggleMouse(false, button);
}

/**
* Special function for sending double clicks, needed for Mac OS X.
* @param button Button to click.
*/
void doubleClick(MMMouseButton button)
{
UINT maxDoubleClickTime = GetDoubleClickTime();
/* Double click for everything else. */
clickMouse(button);
if (maxDoubleClickTime > DEFAULT_DOUBLE_CLICK_INTERVAL_MS) {
microsleep(DEFAULT_DOUBLE_CLICK_INTERVAL_MS);
} else {
microsleep(DEADBEEF_RANDRANGE(1, maxDoubleClickTime));
}
clickMouse(button);
void doubleClick(MMMouseButton button) {
UINT maxDoubleClickTime = GetDoubleClickTime();
/* Double click for everything else. */
clickMouse(button);
if (maxDoubleClickTime > DEFAULT_DOUBLE_CLICK_INTERVAL_MS) {
microsleep(DEFAULT_DOUBLE_CLICK_INTERVAL_MS);
} else {
microsleep(DEADBEEF_RANDRANGE(1, maxDoubleClickTime));
}
clickMouse(button);
}

void scrollMouse(int x, int y)
{
INPUT mouseScrollInputH;
INPUT mouseScrollInputV;

mouseScrollInputH.type = INPUT_MOUSE;
mouseScrollInputH.mi.dx = 0;
mouseScrollInputH.mi.dy = 0;
mouseScrollInputH.mi.dwFlags = MOUSEEVENTF_HWHEEL;
mouseScrollInputH.mi.time = 0;
mouseScrollInputH.mi.dwExtraInfo = 0;
// Flip x to match other platforms.
mouseScrollInputH.mi.mouseData = -x;

mouseScrollInputV.type = INPUT_MOUSE;
mouseScrollInputV.mi.dx = 0;
mouseScrollInputV.mi.dy = 0;
mouseScrollInputV.mi.dwFlags = MOUSEEVENTF_WHEEL;
mouseScrollInputV.mi.time = 0;
mouseScrollInputV.mi.dwExtraInfo = 0;
mouseScrollInputV.mi.mouseData = y;

SendInput(1, &mouseScrollInputH, sizeof(mouseScrollInputH));
SendInput(1, &mouseScrollInputV, sizeof(mouseScrollInputV));
void scrollMouse(int x, int y) {
INPUT mouseScrollInputH;
INPUT mouseScrollInputV;

mouseScrollInputH.type = INPUT_MOUSE;
mouseScrollInputH.mi.dx = 0;
mouseScrollInputH.mi.dy = 0;
mouseScrollInputH.mi.dwFlags = MOUSEEVENTF_HWHEEL;
mouseScrollInputH.mi.time = 0;
mouseScrollInputH.mi.dwExtraInfo = 0;
// Flip x to match other platforms.
mouseScrollInputH.mi.mouseData = -x;

mouseScrollInputV.type = INPUT_MOUSE;
mouseScrollInputV.mi.dx = 0;
mouseScrollInputV.mi.dy = 0;
mouseScrollInputV.mi.dwFlags = MOUSEEVENTF_WHEEL;
mouseScrollInputV.mi.time = 0;
mouseScrollInputV.mi.dwExtraInfo = 0;
mouseScrollInputV.mi.mouseData = y;

SendInput(1, &mouseScrollInputH, sizeof(mouseScrollInputH));
SendInput(1, &mouseScrollInputV, sizeof(mouseScrollInputV));
}