-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathmouse.c
135 lines (116 loc) · 3.7 KB
/
mouse.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include "../mouse.h"
#include "../screen.h"
#include "../microsleep.h"
#include "../deadbeef_rand.h"
#include <math.h> /* For floor() */
#if !defined(M_SQRT2)
#define M_SQRT2 1.4142135623730950488016887 /* Fix for MSVC. */
#endif
/**
* This constant is required as Windows divides the entire
* screen space into 65536 segments in both X and Y axes
* irrespective of resolution
* https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput#remarks
*/
#define ABSOLUTE_COORD_CONST 65536
#define MMMouseToMEventF(down, button) \
(down ? MMMouseDownToMEventF(button) : MMMouseUpToMEventF(button))
#define MMMouseUpToMEventF(button) \
((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))
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);
}
/**
* 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));
}
void dragMouse(MMPoint point, const MMMouseButton button)
{
(void)button;
moveMouse(point);
}
MMPoint getMousePos()
{
POINT point;
GetCursorPos(&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 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 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));
}